Initial intrinsic implementation
This commit is contained in:
committed by
Dmitry Petrov
parent
95c88e4445
commit
204a8c5c14
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
object ArrayConstructor : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArrayGet : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val type = expressionType(expression, context)
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
it.aload(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArrayIterator : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val method = context.state.typeMapper.mapToCallableMethod(expression.descriptor as FunctionDescriptor, false)
|
||||
return IrIntrinsicFunction.create(expression, signature, method.owner) {
|
||||
val methodSignature = "(${method.owner.descriptor})${method.returnType.descriptor}"
|
||||
val intrinsicOwner =
|
||||
if (AsmUtil.isPrimitive(method.owner.elementType))
|
||||
"kotlin/jvm/internal/ArrayIteratorsKt"
|
||||
else
|
||||
"kotlin/jvm/internal/ArrayIteratorKt"
|
||||
it.invokestatic(intrinsicOwner, "iterator", methodSignature, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArrayOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
//do nothing all generated as vararg
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArraySet : IntrinsicMethod() {
|
||||
|
||||
/*TODO return type, types*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val type = expressionType(expression.dispatchReceiver!!, context)
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
it.astore(signature.valueParameters.last().asmType)
|
||||
}
|
||||
}
|
||||
|
||||
/*override fun toCallable(method: CallableMethod): Callable {
|
||||
val type = correctElementType(method.dispatchReceiverType)
|
||||
return object : IntrinsicCallable(
|
||||
Type.VOID_TYPE,
|
||||
listOf(Type.INT_TYPE, type),
|
||||
method.dispatchReceiverType,
|
||||
method.extensionReceiverType
|
||||
) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
v.astore(type)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ArraySize : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
it.arraylength()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
||||
private fun shift(): Boolean =
|
||||
opcode == ISHL || opcode == ISHR || opcode == IUSHR
|
||||
|
||||
/*TODO new return type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val owner = context.state.typeMapper.mapOwner(expression.descriptor)
|
||||
val returnType = signature.returnType
|
||||
val intermediateResultType: Type = numberFunctionOperandType(returnType)
|
||||
val argTypes = if (owner != Type.CHAR_TYPE) {
|
||||
listOf(intermediateResultType, if (shift()) Type.INT_TYPE else intermediateResultType)
|
||||
}
|
||||
else {
|
||||
listOf(Type.CHAR_TYPE, signature.valueParameters[0].asmType)
|
||||
}
|
||||
|
||||
return IrIntrinsicFunction.create(expression, signature, argTypes) {
|
||||
it.visitInsn(returnType.getOpcode(opcode))
|
||||
StackValue.coerce(intermediateResultType, returnType, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class Clone : IntrinsicMethod() {
|
||||
|
||||
/*TODO return type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
|
||||
it.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
class CompareTo : IntrinsicMethod() {
|
||||
private fun genInvoke(type: Type?, v: InstructionAdapter) {
|
||||
when (type) {
|
||||
Type.INT_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false)
|
||||
Type.LONG_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(JJ)I", false)
|
||||
Type.FLOAT_TYPE -> v.invokestatic("java/lang/Float", "compare", "(FF)I", false)
|
||||
Type.DOUBLE_TYPE -> v.invokestatic("java/lang/Double", "compare", "(DD)I", false)
|
||||
else -> throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val parameterType = comparisonOperandType(
|
||||
expressionType(expression.dispatchReceiver ?: expression.extensionReceiver!!, context),
|
||||
signature.valueParameters.single().asmType
|
||||
)
|
||||
return IrIntrinsicFunction.create(expression, signature, listOf(parameterType, parameterType)) {
|
||||
genInvoke(parameterType, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class Concat : IntrinsicMethod() {
|
||||
fun generateImpl(
|
||||
codegen: ExpressionCodegen,
|
||||
v: InstructionAdapter,
|
||||
returnType: Type,
|
||||
element: PsiElement?,
|
||||
arguments: List<KtExpression>,
|
||||
receiver: StackValue
|
||||
): Type {
|
||||
if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) {
|
||||
// LHS + RHS
|
||||
genStringBuilderConstructor(v)
|
||||
codegen.invokeAppend(element.left)
|
||||
codegen.invokeAppend(element.right)
|
||||
}
|
||||
else {
|
||||
// LHS?.plus(RHS)
|
||||
receiver.put(AsmTypes.OBJECT_TYPE, v)
|
||||
genStringBuilderConstructor(v)
|
||||
v.swap()
|
||||
genInvokeAppendMethod(v, returnType)
|
||||
codegen.invokeAppend(arguments.get(0))
|
||||
}
|
||||
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||
return JAVA_STRING_TYPE
|
||||
}
|
||||
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
object : IntrinsicCallable(method) {
|
||||
override fun invokeMethodWithArguments(
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
receiver: StackValue,
|
||||
codegen: ExpressionCodegen
|
||||
): StackValue {
|
||||
if (resolvedCall.call.callElement.parent is KtCallableReferenceExpression) {
|
||||
// NB we come here only in case of inlined callable reference to String::plus.
|
||||
// This will map arguments properly, invoking callbacks defined in Callable.
|
||||
return super.invokeMethodWithArguments(resolvedCall, receiver, codegen)
|
||||
}
|
||||
return StackValue.operation(returnType) {
|
||||
val arguments = resolvedCall.call.valueArguments.map { it.getArgumentExpression()!! }
|
||||
val actualType = generateImpl(
|
||||
codegen, it, returnType,
|
||||
resolvedCall.call.callElement,
|
||||
arguments,
|
||||
StackValue.receiver(resolvedCall, receiver, codegen, this)
|
||||
)
|
||||
StackValue.coerce(actualType, returnType, it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterReceiverGeneration(v: InstructionAdapter) {
|
||||
v.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder")
|
||||
v.dupX1()
|
||||
v.swap()
|
||||
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
|
||||
}
|
||||
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
// String::plus has type String.(Any?) -> String, thus we have no argument type information
|
||||
// in case of callable reference passed to a generic function, e.g.:
|
||||
// charArrayOf('O', 'K').fold("", String::plus)
|
||||
// TODO Make String::plus generic, and invoke proper StringBuilder#append.
|
||||
AsmUtil.genInvokeAppendMethod(v, AsmTypes.OBJECT_TYPE)
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.*
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi2ir.generators.getInfixOperator
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class Equals(val operator: IElementType) : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val binary = expression as IrBinaryPrimitiveImpl
|
||||
var leftType = context.state.typeMapper.mapType(binary.argument0.type)
|
||||
var rightType = context.state.typeMapper.mapType(binary.argument1.type)
|
||||
|
||||
if (isPrimitive(leftType) != isPrimitive(rightType)) {
|
||||
leftType = boxType(leftType)
|
||||
rightType = boxType(rightType)
|
||||
}
|
||||
|
||||
|
||||
return object: IrIntrinsicFunction(expression, signature, listOf(leftType, rightType)) {
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
val opToken = binary.origin
|
||||
if (opToken === KtTokens.EQEQEQ || opToken === KtTokens.EXCLEQEQEQ) {
|
||||
// TODO: always casting to the type of the left operand in case of primitives looks wrong
|
||||
val operandType = if (isPrimitive(leftType)) leftType else OBJECT_TYPE
|
||||
StackValue.cmp(operator, operandType, StackValue.onStack(leftType), StackValue.onStack(rightType))
|
||||
}
|
||||
|
||||
genEqualsForExpressionsOnStack(operator, StackValue.onStack(leftType), StackValue.onStack(rightType)).put(Type.BOOLEAN_TYPE, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class HashCode : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, AsmTypes.OBJECT_TYPE) {
|
||||
it.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class Increment(private val myDelta: Int) : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
genIncrement(signature.returnType, myDelta, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
open class IntrinsicCallable(
|
||||
override val returnType: Type,
|
||||
override val valueParameterTypes: List<Type>,
|
||||
override val dispatchReceiverType: Type?,
|
||||
override val extensionReceiverType: Type?,
|
||||
private val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = { throw UnsupportedOperationException() }
|
||||
) : Callable {
|
||||
|
||||
constructor(
|
||||
callable: CallableMethod,
|
||||
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}
|
||||
) : this(
|
||||
callable.returnType,
|
||||
callable.valueParameterTypes,
|
||||
callable.dispatchReceiverType,
|
||||
callable.extensionReceiverType,
|
||||
invoke
|
||||
)
|
||||
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
invokeIntrinsic(v)
|
||||
}
|
||||
|
||||
open fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
invoke(v)
|
||||
}
|
||||
|
||||
override val parameterTypes: Array<Type>
|
||||
get() = throw UnsupportedOperationException()
|
||||
|
||||
override fun isStaticCall() = false
|
||||
|
||||
override val generateCalleeType: Type?
|
||||
get() = null
|
||||
|
||||
override val owner: Type
|
||||
get() = throw UnsupportedOperationException()
|
||||
|
||||
fun calcReceiverType(): Type =
|
||||
extensionReceiverType ?: dispatchReceiverType!!
|
||||
}
|
||||
|
||||
fun createBinaryIntrinsicCallable(
|
||||
returnType: Type,
|
||||
valueParameterType: Type,
|
||||
thisType: Type? = null,
|
||||
receiverType: Type? = null,
|
||||
lambda: IntrinsicCallable.(v: InstructionAdapter) -> Unit
|
||||
): IntrinsicCallable {
|
||||
assert(AsmUtil.isPrimitive(returnType)) { "Return type of BinaryOp intrinsic should be of primitive type: $returnType" }
|
||||
|
||||
return object : IntrinsicCallable(returnType, listOf(valueParameterType), thisType, receiverType) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
lambda(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createUnaryIntrinsicCallable(
|
||||
callable: CallableMethod,
|
||||
newReturnType: Type? = null,
|
||||
needPrimitiveCheck: Boolean = false,
|
||||
newThisType: Type? = null,
|
||||
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit
|
||||
): IntrinsicCallable {
|
||||
val intrinsic = IntrinsicCallable(
|
||||
newReturnType ?: callable.returnType,
|
||||
callable.valueParameterTypes,
|
||||
newThisType ?: callable.dispatchReceiverType,
|
||||
callable.extensionReceiverType,
|
||||
invoke
|
||||
)
|
||||
assert(intrinsic.valueParameterTypes.isEmpty()) { "Unary operation should not have any parameters" }
|
||||
if (needPrimitiveCheck) {
|
||||
assert(AsmUtil.isPrimitive(intrinsic.returnType)) {
|
||||
"Return type of UnaryPlus intrinsic should be of primitive type: ${intrinsic.returnType}"
|
||||
}
|
||||
}
|
||||
return intrinsic
|
||||
}
|
||||
|
||||
fun createIntrinsicCallable(
|
||||
callable: CallableMethod,
|
||||
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit
|
||||
): IntrinsicCallable {
|
||||
return IntrinsicCallable(callable, invoke)
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
abstract class IntrinsicMethod {
|
||||
|
||||
open fun toCallable(
|
||||
expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext
|
||||
): IrIntrinsicFunction {
|
||||
TODO()
|
||||
}
|
||||
|
||||
|
||||
open fun toCallable(
|
||||
fd: FunctionDescriptor,
|
||||
isSuper: Boolean,
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
codegen: ExpressionCodegen
|
||||
): Callable {
|
||||
throw UnsupportedOperationException("Not implemented")
|
||||
}
|
||||
|
||||
open fun toCallable(method: CallableMethod): Callable {
|
||||
throw UnsupportedOperationException("Not implemented")
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun calcReceiverType(call: IrMemberAccessExpression, context: JvmBackendContext): Type {
|
||||
return context.state.typeMapper.mapType(call.dispatchReceiver?.type ?: call.extensionReceiver!!.type)
|
||||
}
|
||||
|
||||
fun expressionType(expression: IrExpression, context: JvmBackendContext): Type {
|
||||
return context.state.typeMapper.mapType(expression.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class IntrinsicMethods {
|
||||
public static final String INTRINSICS_CLASS_NAME = "kotlin/jvm/internal/Intrinsics";
|
||||
|
||||
private static final FqName KOTLIN_JVM = new FqName("kotlin.jvm");
|
||||
/* package */ static final FqNameUnsafe RECEIVER_PARAMETER_FQ_NAME = new FqNameUnsafe("T");
|
||||
|
||||
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
||||
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
|
||||
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
|
||||
private static final IntrinsicMethod INV = new Inv();
|
||||
private static final IntrinsicMethod RANGE_TO = new RangeTo();
|
||||
private static final IntrinsicMethod INC = new Increment(1);
|
||||
private static final IntrinsicMethod DEC = new Increment(-1);
|
||||
private static final IntrinsicMethod HASH_CODE = new HashCode();
|
||||
|
||||
private static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
||||
private static final Equals EQUALS = new Equals(KtTokens.EQEQ);
|
||||
private static final IteratorNext ITERATOR_NEXT = new IteratorNext();
|
||||
private static final ArraySet ARRAY_SET = new ArraySet();
|
||||
private static final ArrayGet ARRAY_GET = new ArrayGet();
|
||||
private static final StringPlus STRING_PLUS = new StringPlus();
|
||||
private static final ToString TO_STRING = new ToString();
|
||||
private static final Clone CLONE = new Clone();
|
||||
|
||||
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
|
||||
private final IntrinsicsMap intrinsicsMap = new IntrinsicsMap();
|
||||
|
||||
public IntrinsicMethods() {
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, RECEIVER_PARAMETER_FQ_NAME, "javaClass", -1, JavaClassProperty.INSTANCE);
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.kClass, "java", -1, new KClassJavaProperty());
|
||||
intrinsicsMap.registerIntrinsic(KotlinBuiltIns.FQ_NAMES.kCallable.toSafe(), null, "name", -1, new KCallableNameProperty());
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorEnter", 1, MonitorInstruction.MONITOR_ENTER);
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorExit", 1, MonitorInstruction.MONITOR_EXIT);
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.array, "isArrayOf", 0, new IsArrayOf());
|
||||
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOf", 1, new ArrayOf());
|
||||
|
||||
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
|
||||
for (Name method : primitiveCastMethods) {
|
||||
String methodName = method.asString();
|
||||
declareIntrinsicFunction(FQ_NAMES.number, methodName, 0, NUMBER_CAST);
|
||||
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
|
||||
declareIntrinsicFunction(type.getTypeFqName(), methodName, 0, NUMBER_CAST);
|
||||
}
|
||||
}
|
||||
|
||||
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
|
||||
FqName typeFqName = type.getTypeFqName();
|
||||
declareIntrinsicFunction(typeFqName, "plus", 0, UNARY_PLUS);
|
||||
declareIntrinsicFunction(typeFqName, "unaryPlus", 0, UNARY_PLUS);
|
||||
declareIntrinsicFunction(typeFqName, "minus", 0, UNARY_MINUS);
|
||||
declareIntrinsicFunction(typeFqName, "unaryMinus", 0, UNARY_MINUS);
|
||||
declareIntrinsicFunction(typeFqName, "inv", 0, INV);
|
||||
declareIntrinsicFunction(typeFqName, "rangeTo", 1, RANGE_TO);
|
||||
declareIntrinsicFunction(typeFqName, "inc", 0, INC);
|
||||
declareIntrinsicFunction(typeFqName, "dec", 0, DEC);
|
||||
}
|
||||
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
FqName typeFqName = type.getTypeFqName();
|
||||
declareIntrinsicFunction(typeFqName, "equals", 1, EQUALS);
|
||||
declareIntrinsicFunction(typeFqName, "hashCode", 0, HASH_CODE);
|
||||
declareIntrinsicFunction(typeFqName, "toString", 0, TO_STRING);
|
||||
|
||||
intrinsicsMap.registerIntrinsic(
|
||||
BUILT_INS_PACKAGE_FQ_NAME, null, StringsKt.decapitalize(type.getArrayTypeName().asString()) + "Of", 1, new ArrayOf()
|
||||
);
|
||||
}
|
||||
|
||||
declareBinaryOp("plus", IADD);
|
||||
declareBinaryOp("minus", ISUB);
|
||||
declareBinaryOp("times", IMUL);
|
||||
declareBinaryOp("div", IDIV);
|
||||
declareBinaryOp("mod", IREM);
|
||||
declareBinaryOp("shl", ISHL);
|
||||
declareBinaryOp("shr", ISHR);
|
||||
declareBinaryOp("ushr", IUSHR);
|
||||
declareBinaryOp("and", IAND);
|
||||
declareBinaryOp("or", IOR);
|
||||
declareBinaryOp("xor", IXOR);
|
||||
|
||||
declareIntrinsicFunction(FQ_NAMES._boolean, "not", 0, new Not());
|
||||
|
||||
declareIntrinsicFunction(FQ_NAMES.string, "plus", 1, new Concat());
|
||||
declareIntrinsicFunction(FQ_NAMES.string, "get", 1, new StringGetChar());
|
||||
|
||||
declareIntrinsicFunction(FQ_NAMES.cloneable, "clone", 0, CLONE);
|
||||
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.FQ_NAMES.any, "toString", 0, TO_STRING);
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.FQ_NAMES.string, "plus", 1, STRING_PLUS);
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOfNulls", 1, new NewArray());
|
||||
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
declareIntrinsicFunction(type.getTypeFqName(), "compareTo", 1, new CompareTo());
|
||||
declareIntrinsicFunction(COLLECTIONS_PACKAGE_FQ_NAME.child(Name.identifier(type.getTypeName().asString() + "Iterator")), "next", 0, ITERATOR_NEXT);
|
||||
}
|
||||
|
||||
declareArrayMethods();
|
||||
}
|
||||
|
||||
private void declareArrayMethods() {
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
declareArrayMethods(jvmPrimitiveType.getPrimitiveType().getArrayTypeFqName());
|
||||
}
|
||||
declareArrayMethods(FQ_NAMES.array.toSafe());
|
||||
}
|
||||
|
||||
private void declareArrayMethods(@NotNull FqName arrayTypeFqName) {
|
||||
declareIntrinsicFunction(arrayTypeFqName, "size", -1, ARRAY_SIZE);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "set", 2, ARRAY_SET);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "get", 1, ARRAY_GET);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "clone", 0, CLONE);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "iterator", 0, ARRAY_ITERATOR);
|
||||
declareIntrinsicFunction(arrayTypeFqName, "<init>", 2, ArrayConstructor.INSTANCE);
|
||||
}
|
||||
|
||||
private void declareBinaryOp(@NotNull String methodName, int opcode) {
|
||||
BinaryOp op = new BinaryOp(opcode);
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
declareIntrinsicFunction(type.getTypeFqName(), methodName, 1, op);
|
||||
}
|
||||
}
|
||||
|
||||
private void declareIntrinsicFunction(
|
||||
@NotNull FqName classFqName,
|
||||
@NotNull String methodName,
|
||||
int arity,
|
||||
@NotNull IntrinsicMethod implementation
|
||||
) {
|
||||
intrinsicsMap.registerIntrinsic(classFqName, null, methodName, arity, implementation);
|
||||
}
|
||||
|
||||
private void declareIntrinsicFunction(
|
||||
@NotNull FqNameUnsafe classFqName,
|
||||
@NotNull String methodName,
|
||||
int arity,
|
||||
@NotNull IntrinsicMethod implementation
|
||||
) {
|
||||
intrinsicsMap.registerIntrinsic(classFqName.toSafe(), null, methodName, arity, implementation);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
|
||||
return intrinsicsMap.getIntrinsic(descriptor);
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
class IntrinsicsMap {
|
||||
private static final class Key {
|
||||
private final FqNameUnsafe owner;
|
||||
private final FqNameUnsafe receiverParameter;
|
||||
private final String name;
|
||||
private final int valueParameterCount;
|
||||
|
||||
private Key(@NotNull FqNameUnsafe owner, @Nullable FqNameUnsafe receiverParameter, @NotNull String name, int valueParameterCount) {
|
||||
this.owner = owner;
|
||||
this.receiverParameter = receiverParameter;
|
||||
this.name = name;
|
||||
this.valueParameterCount = valueParameterCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Key key = (Key) o;
|
||||
|
||||
if (valueParameterCount != key.valueParameterCount) return false;
|
||||
if (!name.equals(key.name)) return false;
|
||||
if (!owner.equals(key.owner)) return false;
|
||||
if (receiverParameter == null ? key.receiverParameter != null : !receiverParameter.equals(key.receiverParameter)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = owner.hashCode();
|
||||
result = 31 * result + name.hashCode();
|
||||
result = 31 * result + valueParameterCount;
|
||||
result = 31 * result + (receiverParameter != null ? receiverParameter.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static int valueParameterCountForKey(@NotNull CallableMemberDescriptor member) {
|
||||
if (member instanceof PropertyDescriptor) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return member.getValueParameters().size();
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<Key, IntrinsicMethod> intrinsicsMap = Maps.newHashMap();
|
||||
|
||||
|
||||
/**
|
||||
* @param valueParameterCount -1 for property
|
||||
*/
|
||||
public void registerIntrinsic(
|
||||
@NotNull FqName owner,
|
||||
@Nullable FqNameUnsafe receiverParameter,
|
||||
@NotNull String name,
|
||||
int valueParameterCount,
|
||||
@NotNull IntrinsicMethod impl
|
||||
) {
|
||||
intrinsicsMap.put(new Key(owner.toUnsafe(), receiverParameter, name, valueParameterCount), impl);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
|
||||
Key key = new Key(
|
||||
DescriptorUtils.getFqName(descriptor.getContainingDeclaration()),
|
||||
getReceiverParameterFqName(descriptor),
|
||||
descriptor.getName().asString(),
|
||||
valueParameterCountForKey(descriptor)
|
||||
);
|
||||
return intrinsicsMap.get(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FqNameUnsafe getReceiverParameterFqName(@NotNull CallableMemberDescriptor descriptor) {
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
if (receiverParameter == null) return null;
|
||||
|
||||
ClassifierDescriptor classifier = receiverParameter.getType().getConstructor().getDeclarationDescriptor();
|
||||
if (classifier == null) return null;
|
||||
|
||||
if (classifier instanceof TypeParameterDescriptor) {
|
||||
return IntrinsicMethods.RECEIVER_PARAMETER_FQ_NAME;
|
||||
}
|
||||
|
||||
return DescriptorUtils.getFqName(classifier);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class Inv : IntrinsicMethod() {
|
||||
/*TODO new this type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val returnType = signature.returnType
|
||||
val type = numberFunctionOperandType(returnType)
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
if (returnType == Type.LONG_TYPE) {
|
||||
it.lconst(-1)
|
||||
}
|
||||
else {
|
||||
it.iconst(-1)
|
||||
}
|
||||
it.xor(returnType)
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
|
||||
open class IrIntrinsicFunction(
|
||||
val expression: IrMemberAccessExpression,
|
||||
val signature: JvmMethodSignature,
|
||||
val argsTypes: List<Type> = signature.valueParameters.map { it.asmType }
|
||||
) : Callable {
|
||||
override val owner: Type
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val dispatchReceiverType: Type?
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val extensionReceiverType: Type?
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val generateCalleeType: Type?
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val valueParameterTypes: List<Type>
|
||||
get() = signature.valueParameters.map { it.asmType }
|
||||
override val parameterTypes: Array<Type>
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val returnType: Type
|
||||
get() = signature.returnType
|
||||
|
||||
override fun isStaticCall(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
TODO("not implemented for $this")
|
||||
}
|
||||
|
||||
open fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo):StackValue {
|
||||
val args = mutableListOf(expression.dispatchReceiver, expression.extensionReceiver)
|
||||
args.addAll(expression.descriptor.valueParameters.mapIndexed {
|
||||
i, valueParameterDescriptor ->
|
||||
expression.getValueArgument(i)
|
||||
})
|
||||
args.filterNotNull().forEachIndexed { i, irExpression -> genArg(irExpression, codegen, i, data) }
|
||||
genInvokeInstruction(v)
|
||||
return StackValue.onStack(returnType)
|
||||
}
|
||||
|
||||
fun genArg(expression: IrExpression, codegen: ExpressionCodegen, index: Int, data: BlockInfo) {
|
||||
codegen.gen(expression, argsTypes[index], data)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
argsTypes: List<Type> = signature.valueParameters.map { it.asmType },
|
||||
invokeInstuction: (InstructionAdapter) -> Unit): IrIntrinsicFunction {
|
||||
return object : IrIntrinsicFunction(expression, signature, argsTypes) {
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
invokeInstuction(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun create(expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext,
|
||||
invokeInstuction: (InstructionAdapter) -> Unit): IrIntrinsicFunction {
|
||||
val args = (expression.dispatchReceiver?.let { listOf(context.state.typeMapper.mapType(it.type)) } ?: emptyList<Type>()) +
|
||||
signature.valueParameters.map { it.asmType }
|
||||
return object : IrIntrinsicFunction(expression, signature, args) {
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
invokeInstuction(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun create(expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
type: Type,
|
||||
invokeInstuction: (InstructionAdapter) -> Unit): IrIntrinsicFunction {
|
||||
return create(expression, signature, listOf(type), invokeInstuction)
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
|
||||
class IrIntrinsicMethods(irBuiltIns: IrBuiltIns) {
|
||||
|
||||
private val intrinsics = IntrinsicMethods()
|
||||
|
||||
private val irMapping = hashMapOf<CallableMemberDescriptor, IntrinsicMethod>()
|
||||
|
||||
init {
|
||||
irMapping.put(irBuiltIns.eqeq, Equals(KtTokens.EQEQ))
|
||||
irMapping.put(irBuiltIns.eqeqeq, Equals(KtTokens.EQEQEQ))
|
||||
irMapping.put(irBuiltIns.booleanNot, Not())
|
||||
}
|
||||
|
||||
fun getIntrinsic(descriptor: CallableMemberDescriptor): IntrinsicMethod? {
|
||||
return intrinsics.getIntrinsic(descriptor) ?:
|
||||
(if (descriptor is PropertyAccessorDescriptor) intrinsics.getIntrinsic(descriptor.correspondingProperty) else null) ?:
|
||||
irMapping[descriptor]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class IsArrayOf : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val typeMapper = context.state.typeMapper
|
||||
|
||||
val descriptor = expression.descriptor
|
||||
val builtIns = descriptor.module.builtIns
|
||||
assert(descriptor.typeParameters.size == 1) {
|
||||
"Expected only one type parameter for Any?.isArrayOf(), got: ${descriptor.typeParameters}"
|
||||
}
|
||||
/*TODO original?*/
|
||||
val elementType = expression.getTypeArgument(descriptor.original.typeParameters.first())!!
|
||||
val arrayKtType = builtIns.getArrayType(Variance.INVARIANT, elementType)
|
||||
val arrayType = typeMapper.mapType(arrayKtType)
|
||||
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
it.instanceOf(arrayType)
|
||||
}
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.COLLECTIONS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.fileClasses.internalNameWithoutInnerClasses
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
class IteratorNext : IntrinsicMethod() {
|
||||
|
||||
/*TODO new return type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val type = AsmUtil.unboxType(signature.returnType)
|
||||
val newMethod = with(signature.asmMethod) {
|
||||
Method(name, type, argumentTypes)
|
||||
}
|
||||
|
||||
val newSignature = JvmMethodSignature(newMethod, signature.valueParameters)
|
||||
return IrIntrinsicFunction.create(expression, newSignature, AsmTypes.OBJECT_TYPE) {
|
||||
val primitiveClassName = getKotlinPrimitiveClassName(type)
|
||||
it.invokevirtual(
|
||||
getPrimitiveIteratorType(primitiveClassName).internalName,
|
||||
"next${primitiveClassName.asString()}",
|
||||
"()" + type.descriptor,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Type.CHAR_TYPE -> "Char"
|
||||
private fun getKotlinPrimitiveClassName(type: Type): Name {
|
||||
return JvmPrimitiveType.get(type.className).primitiveType.typeName
|
||||
}
|
||||
|
||||
// "Char" -> type for kotlin.collections.CharIterator
|
||||
fun getPrimitiveIteratorType(primitiveClassName: Name): Type {
|
||||
val iteratorName = Name.identifier(primitiveClassName.asString() + "Iterator")
|
||||
return Type.getObjectType(COLLECTIONS_PACKAGE_FQ_NAME.child(iteratorName).internalNameWithoutInnerClasses)
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.boxType
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
object JavaClassProperty : IntrinsicMethod() {
|
||||
fun generate(
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
codegen: ExpressionCodegen,
|
||||
returnType: Type,
|
||||
receiver: StackValue
|
||||
): StackValue? =
|
||||
StackValue.operation(returnType) {
|
||||
val actualType = generateImpl(it, receiver)
|
||||
StackValue.coerce(actualType, returnType, it)
|
||||
}
|
||||
|
||||
fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type {
|
||||
val type = receiver.type
|
||||
if (isPrimitive(type)) {
|
||||
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
|
||||
receiver.put(type, v)
|
||||
AsmUtil.pop(v, type)
|
||||
}
|
||||
v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
else {
|
||||
receiver.put(type, v)
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
|
||||
}
|
||||
|
||||
return getType(Class::class.java)
|
||||
}
|
||||
|
||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
||||
val classType = codegen.getState().typeMapper.mapType(resolvedCall.call.dispatchReceiver!!.type)
|
||||
return object : IntrinsicCallable(getType(Class::class.java), listOf(), classType, null) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
if (isPrimitive(classType)) {
|
||||
v.getstatic(boxType(classType).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
else {
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isStaticCall() = isPrimitive(classType)
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE
|
||||
|
||||
class KCallableNameProperty : IntrinsicMethod() {
|
||||
fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? {
|
||||
val expressionReceiver = resolvedCall!!.dispatchReceiver as? ExpressionReceiver ?: return null
|
||||
val expression = expressionReceiver.expression as? KtCallableReferenceExpression ?: return null
|
||||
|
||||
val receiverExpression = expression.receiverExpression
|
||||
val lhs = receiverExpression?.let { codegen.bindingContext.get(DOUBLE_COLON_LHS, it) }
|
||||
|
||||
val callableReference = expression.callableReference
|
||||
val descriptor = callableReference.getResolvedCall(codegen.bindingContext)?.resultingDescriptor ?: return null
|
||||
|
||||
return StackValue.operation(returnType) { iv ->
|
||||
// Generate the left-hand side of a bound callable reference expression
|
||||
if (lhs is DoubleColonLHS.Expression) {
|
||||
codegen.gen(receiverExpression, VOID_TYPE)
|
||||
}
|
||||
iv.aconst(descriptor.name.asString())
|
||||
StackValue.coerce(JAVA_STRING_TYPE, returnType, iv)
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class KClassJavaProperty : IntrinsicMethod() {
|
||||
fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? {
|
||||
val receiverValue = resolvedCall!!.extensionReceiver as? ExpressionReceiver ?: return null
|
||||
val classLiteralExpression = receiverValue.expression as? KtClassLiteralExpression ?: return null
|
||||
val receiverExpression = classLiteralExpression.receiverExpression ?: return null
|
||||
val lhs = codegen.bindingContext.get(DOUBLE_COLON_LHS, receiverExpression) ?: return null
|
||||
val value = codegen.generateClassLiteralReference(lhs, receiverExpression, /* wrapIntoKClass = */ false)
|
||||
return StackValue.coercion(value, returnType)
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class MonitorInstruction private constructor(private val opcode: Int) : IntrinsicMethod() {
|
||||
companion object {
|
||||
@JvmField
|
||||
val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
|
||||
|
||||
@JvmField
|
||||
val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
|
||||
}
|
||||
|
||||
/*TODO void return type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, OBJECT_TYPE) {
|
||||
it.visitInsn(opcode)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class NewArray : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val ktType = expression.type
|
||||
return object : IrIntrinsicFunction(expression, signature) {
|
||||
override fun invoke(v: InstructionAdapter, codegen: org.jetbrains.kotlin.backend.jvm.ExpressionCodegen, data: BlockInfo): StackValue {
|
||||
super.invoke(v, codegen, data)
|
||||
codegen.newArrayInstruction(ktType)
|
||||
return StackValue.onStack(returnType)
|
||||
}
|
||||
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtPrefixExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class Not : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(Type.BOOLEAN_TYPE, it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
object : IntrinsicCallable(method) {
|
||||
override fun invokeMethodWithArguments(
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
receiver: StackValue,
|
||||
codegen: ExpressionCodegen
|
||||
): StackValue {
|
||||
val element = resolvedCall.call.callElement
|
||||
val stackValue =
|
||||
if (element is KtPrefixExpression) {
|
||||
codegen.gen(element.baseExpression)
|
||||
}
|
||||
else {
|
||||
StackValue.receiver(resolvedCall, receiver, codegen, this)
|
||||
}
|
||||
return StackValue.not(stackValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class NumberCast : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
StackValue.coerce(calcReceiverType(expression, context), signature.returnType, it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.Type.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
class RangeTo : IntrinsicMethod() {
|
||||
private fun rangeTypeToPrimitiveType(rangeType: Type): Type {
|
||||
val fqName = rangeType.internalName
|
||||
val name = fqName.substringAfter("kotlin/ranges/").substringBefore("Range")
|
||||
return when (name) {
|
||||
"Double" -> DOUBLE_TYPE
|
||||
"Float" -> FLOAT_TYPE
|
||||
"Long" -> LONG_TYPE
|
||||
"Int" -> INT_TYPE
|
||||
"Short" -> SHORT_TYPE
|
||||
"Char" -> CHAR_TYPE
|
||||
"Byte" -> BYTE_TYPE
|
||||
else -> throw IllegalStateException("RangeTo intrinsic can only work for primitive types: $fqName")
|
||||
}
|
||||
}
|
||||
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
val argType = rangeTypeToPrimitiveType(signature.returnType)
|
||||
return object: IrIntrinsicFunction(expression, signature, listOf(argType) + signature.valueParameters.map { argType }) {
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
v.invokespecial(signature.returnType.internalName, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, argType, argType), false)
|
||||
}
|
||||
|
||||
override fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo): StackValue {
|
||||
v.anew(returnType)
|
||||
v.dup()
|
||||
return super.invoke(v, codegen, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// override fun toCallable(method: CallableMethod): Callable {
|
||||
// val argType = rangeTypeToPrimitiveType(method.returnType)
|
||||
// return object : IntrinsicCallable(
|
||||
// method.returnType,
|
||||
// method.valueParameterTypes.map { argType },
|
||||
// nullOr(method.dispatchReceiverType, argType),
|
||||
// nullOr(method.extensionReceiverType, argType)
|
||||
// ) {
|
||||
// override fun afterReceiverGeneration(v: InstructionAdapter) {
|
||||
// v.anew(returnType)
|
||||
// when (argType.size) {
|
||||
// 1 -> {
|
||||
// v.dupX1()
|
||||
// v.swap()
|
||||
// }
|
||||
// 2 -> {
|
||||
// v.dup()
|
||||
// v.dup2X2()
|
||||
// v.pop2()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
// v.invokespecial(returnType.internalName, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, argType, argType), false)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
|
||||
class StringGetChar : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
|
||||
class StringPlus : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus",
|
||||
"(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class ToString : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
it.neg(AsmUtil.numberFunctionOperandType(signature.returnType))
|
||||
}
|
||||
}
|
||||
|
||||
override fun toCallable(method: CallableMethod): Callable {
|
||||
val type = AsmUtil.stringValueOfType(method.dispatchReceiverType ?: method.extensionReceiverType)
|
||||
return createUnaryIntrinsicCallable(method, newThisType = type) {
|
||||
it.invokestatic("java/lang/String", "valueOf", "(${type.descriptor})Ljava/lang/String;", false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class UnaryMinus : IntrinsicMethod() {
|
||||
/*TODO return type*/
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
it.neg(numberFunctionOperandType(signature.returnType))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class UnaryPlus : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user