From 4a66ab3627f101ceaa5916609adafca9d44f5a90 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 2 Oct 2014 15:10:39 +0400 Subject: [PATCH] Support generic array creation for reified inlined --- .../jet/codegen/ExpressionCodegen.java | 60 ++++++++- .../jet/codegen/inline/InlineCodegen.java | 9 +- .../jet/codegen/inline/ReifiedTypeInliner.kt | 125 ++++++++++++++++++ .../calls/TypeParameterAsReifiedCheck.java | 6 +- .../boxWithStdlib/reified/newArrayInt.kt | 13 ++ .../reified/recursiveNewArray.kt | 18 +++ .../reified/sameIndexRecursive.kt | 22 +++ ...lackBoxWithStdlibCodegenTestGenerated.java | 29 +++- .../src/kotlin/jvm/internal/Intrinsics.java | 8 ++ 9 files changed, 281 insertions(+), 9 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reified/newArrayInt.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reified/recursiveNewArray.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reified/sameIndexRecursive.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 6acfdc38247..249e5484a53 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -30,9 +30,7 @@ import org.jetbrains.jet.backend.common.CodegenUtil; import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.context.*; -import org.jetbrains.jet.codegen.inline.InlineCodegen; -import org.jetbrains.jet.codegen.inline.InlineCodegenUtil; -import org.jetbrains.jet.codegen.inline.NameGenerator; +import org.jetbrains.jet.codegen.inline.*; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.jet.codegen.state.GenerationState; @@ -2186,8 +2184,8 @@ public class ExpressionCodegen extends JetVisitor implem resolvedCall = ((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall(); } + CallGenerator callGenerator = getOrCreateCallGenerator(resolvedCall); CallableDescriptor descriptor = resolvedCall.getResultingDescriptor(); - CallGenerator callGenerator = getOrCreateCallGenerator(descriptor, resolvedCall.getCall().getCallElement()); assert callGenerator == defaultCallGenerator || !tailRecursionCodegen.isTailRecursion(resolvedCall) : "Tail recursive method can't be inlined: " + descriptor; @@ -2230,7 +2228,11 @@ public class ExpressionCodegen extends JetVisitor implem } @NotNull - protected CallGenerator getOrCreateCallGenerator(@NotNull CallableDescriptor descriptor, @Nullable JetElement callElement) { + protected CallGenerator getOrCreateCallGenerator( + @NotNull CallableDescriptor descriptor, + @Nullable JetElement callElement, + @Nullable ReifiedTypeParameterMappings reifierTypeParameterMappings + ) { if (callElement == null) return defaultCallGenerator; boolean isInline = state.isInlineEnabled() && @@ -2240,7 +2242,43 @@ public class ExpressionCodegen extends JetVisitor implem if (!isInline) return defaultCallGenerator; SimpleFunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((SimpleFunctionDescriptor) descriptor.getOriginal()); - return new InlineCodegen(this, state, original, callElement); + return new InlineCodegen(this, state, original, callElement, reifierTypeParameterMappings); + } + + @NotNull + public CallGenerator getOrCreateCallGenerator(@NotNull FunctionDescriptor descriptor, @Nullable JetNamedFunction function) { + return getOrCreateCallGenerator(descriptor, function, null); + } + + @NotNull + private CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall resolvedCall) { + Map typeArguments = resolvedCall.getTypeArguments(); + ReifiedTypeParameterMappings mappings = new ReifiedTypeParameterMappings(typeArguments.size()); + for (Map.Entry entry : typeArguments.entrySet()) { + TypeParameterDescriptor key = entry.getKey(); + if (!key.isReified()) continue; + + TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(entry.getValue()); + if (parameterDescriptor == null) { + // type is not generic + // boxType call needed because inlined method is compiled for T as java/lang/Object + mappings.addParameterMappingToType( + key.getIndex(), + key.getName().getIdentifier(), + boxType(asmType(entry.getValue())) + ); + } + else { + mappings.addParameterMappingToNewParameter( + key.getIndex(), + key.getName().getIdentifier(), + parameterDescriptor.getIndex() + ); + } + } + return getOrCreateCallGenerator( + resolvedCall.getResultingDescriptor(), resolvedCall.getCall().getCallElement(), mappings + ); } public void generateReceiverValue(@NotNull ReceiverValue receiverValue, @NotNull Type type) { @@ -3373,6 +3411,16 @@ public class ExpressionCodegen extends JetVisitor implem if (isArray) { gen(args.get(0), Type.INT_TYPE); + TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull( + arrayType.getArguments().get(0).getType() + ); + if (parameterDescriptor != null && parameterDescriptor.isReified()) { + v.iconst(parameterDescriptor.getIndex()); + v.invokestatic( + IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME, + Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE), false + ); + } v.newarray(boxType(asmType(arrayType.getArguments().get(0).getType()))); } else { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java index b96fa0b210e..fc45fc5ca28 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java @@ -76,13 +76,16 @@ public class InlineCodegen implements CallGenerator { protected final ParametersBuilder invocationParamBuilder = ParametersBuilder.newBuilder(); protected final Map expressionMap = new HashMap(); + private final ReifiedTypeInliner reifiedTypeInliner; + private LambdaInfo activeLambda; public InlineCodegen( @NotNull ExpressionCodegen codegen, @NotNull GenerationState state, @NotNull SimpleFunctionDescriptor functionDescriptor, - @NotNull JetElement callElement + @NotNull JetElement callElement, + @Nullable ReifiedTypeParameterMappings typeParameterMappings ) { assert functionDescriptor.getInlineStrategy().isInline() : "InlineCodegen could inline only inline function but " + functionDescriptor; @@ -91,6 +94,9 @@ public class InlineCodegen implements CallGenerator { this.codegen = codegen; this.callElement = callElement; this.functionDescriptor = functionDescriptor.getOriginal(); + + reifiedTypeInliner = new ReifiedTypeInliner(typeParameterMappings); + initialFrameSize = codegen.getFrameMap().getCurrentSize(); context = (MethodContext) getContext(functionDescriptor, state); @@ -200,6 +206,7 @@ public class InlineCodegen implements CallGenerator { } private InlineResult inlineCall(MethodNode node) { + reifiedTypeInliner.reifyInstructions(node.instructions); generateClosuresBodies(); //through generation captured parameters will be added to invocationParamBuilder diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt new file mode 100644 index 00000000000..a14ab3c73d0 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ReifiedTypeInliner.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2010-2014 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.jet.codegen.inline + +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.tree.InsnList +import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode +import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.tree.IntInsnNode +import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode +import org.jetbrains.org.objectweb.asm.tree.InsnNode +import org.jetbrains.org.objectweb.asm.tree.MethodNode +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter +import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods +import kotlin.platform.platformStatic +import org.jetbrains.org.objectweb.asm.tree.LdcInsnNode +import java.util.ArrayList + +public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) { + + class object { + public val NEW_ARRAY_MARKER_METHOD_NAME: String = "reifyNewArray" + } + + public fun reifyInstructions(instructions: InsnList) { + if (parametersMapping == null) return + for (insn in instructions.toArray()) { + if (isReifiedMarker(insn)) { + processReifyMarker(insn as MethodInsnNode, instructions) + } + } + } + + private fun isReifiedMarker(insn: AbstractInsnNode): Boolean { + if (insn.getOpcode() != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false + return insn.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME && insn.name.startsWith("reify") + } + + private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList) { + val mapping = getTypeParameterMapping(insn) ?: return + + if (mapping.asmType != null) { + if (!when (insn.name) { + NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, mapping.asmType) + else -> false + }) { + return + } + instructions.remove(insn.getPrevious()!!) + instructions.remove(insn) + } else { + instructions.set(insn.getPrevious()!!, iconstInsn(mapping.newIndex!!)) + } + } + + private fun processNewArray(insn: MethodInsnNode, parameter: Type): Boolean { + if (insn.getNext()?.getOpcode() != Opcodes.ANEWARRAY) return false + val next = insn.getNext() as TypeInsnNode + next.desc = parameter.getInternalName() + return true + } + + private fun getParameterIndex(insn: MethodInsnNode): Int? { + val prev = insn.getPrevious()!! + + return when (prev.getOpcode()) { + Opcodes.ICONST_0 -> 0 + Opcodes.ICONST_1 -> 1 + Opcodes.ICONST_2 -> 2 + Opcodes.ICONST_3 -> 3 + Opcodes.ICONST_4 -> 4 + Opcodes.ICONST_5 -> 5 + Opcodes.BIPUSH, Opcodes.SIPUSH -> (prev as IntInsnNode).operand + Opcodes.LDC -> (prev as LdcInsnNode).cst as Int + else -> throw AssertionError("Unexpected opcode ${prev.getOpcode()}") + } + } + + private fun getTypeParameterMapping(insn: MethodInsnNode): ReifiedTypeParameterMapping? { + return parametersMapping?.get(getParameterIndex(insn) ?: return null) + } +} + +public class ReifiedTypeParameterMappings(private val size: Int) { + private val mappingsByIndex = arrayOfNulls(size) + private val indexByParameterName = hashMapOf() + + public fun addParameterMappingToType(index: Int, name: String, asmType: Type) { + mappingsByIndex[index] = ReifiedTypeParameterMapping(name, asmType, null) + indexByParameterName[name] = index + } + + public fun addParameterMappingToNewParameter(index: Int, name: String, newIndex: Int) { + mappingsByIndex[index] = ReifiedTypeParameterMapping(name, null, newIndex) + indexByParameterName[name] = index + } + + fun get(index: Int) = mappingsByIndex[index] + fun get(name: String): ReifiedTypeParameterMapping? { + return this[indexByParameterName[name] ?: return null] + } +} + +public class ReifiedTypeParameterMapping(val name: String, val asmType: Type?, val newIndex: Int?) + +private fun iconstInsn(n: Int): AbstractInsnNode { + val node = MethodNode() + InstructionAdapter(node).iconst(n) + return node.instructions.getFirst()!! +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TypeParameterAsReifiedCheck.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TypeParameterAsReifiedCheck.java index 335bd02682c..73913c8462f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TypeParameterAsReifiedCheck.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TypeParameterAsReifiedCheck.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.calls; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.JetExpression; @@ -38,7 +39,10 @@ public class TypeParameterAsReifiedCheck implements CallResolverExtension { for (Map.Entry entry : typeArguments.entrySet()) { TypeParameterDescriptor parameter = entry.getKey(); JetType argument = entry.getValue(); - if (parameter.isReified() && argument.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { + ClassifierDescriptor argumentDeclarationDescription = argument.getConstructor().getDeclarationDescriptor(); + if (parameter.isReified() && argumentDeclarationDescription instanceof TypeParameterDescriptor && + !((TypeParameterDescriptor) argumentDeclarationDescription).isReified() + ) { JetExpression callee = context.call.getCalleeExpression(); PsiElement element = callee != null ? callee : context.call.getCallElement(); context.trace.report(Errors.TYPE_PARAMETER_AS_REIFIED.on(element, typeArguments.keySet().iterator().next())); diff --git a/compiler/testData/codegen/boxWithStdlib/reified/newArrayInt.kt b/compiler/testData/codegen/boxWithStdlib/reified/newArrayInt.kt new file mode 100644 index 00000000000..10d5f1c9729 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/newArrayInt.kt @@ -0,0 +1,13 @@ +import kotlin.InlineOption.* + +inline fun createArray(n: Int, inlineOptions(ONLY_LOCAL_RETURN) block: () -> T): Array { + return Array(n) { block() } +} + +fun box(): String { + + val x = createArray(5) { 3 } + + assert(x.all { it == 3 }) + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/reified/recursiveNewArray.kt b/compiler/testData/codegen/boxWithStdlib/reified/recursiveNewArray.kt new file mode 100644 index 00000000000..b55671552f8 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/recursiveNewArray.kt @@ -0,0 +1,18 @@ +import kotlin.InlineOption.* + +inline fun createArray(n: Int, inlineOptions(ONLY_LOCAL_RETURN) block: () -> T): Array { + return Array(n) { block() } +} + +inline fun recursive( + inlineOptions(ONLY_LOCAL_RETURN) block: () -> R +): Array { + return createArray(5) { block() } +} + +fun box(): String { + val x = recursive(){ "abc" } + + assert(x.all { it == "abc" }) + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/reified/sameIndexRecursive.kt b/compiler/testData/codegen/boxWithStdlib/reified/sameIndexRecursive.kt new file mode 100644 index 00000000000..f669fa83daa --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reified/sameIndexRecursive.kt @@ -0,0 +1,22 @@ +import kotlin.InlineOption.* + +inline fun createArray(n: Int, inlineOptions(ONLY_LOCAL_RETURN) block: () -> Pair): Pair, Array> { + return Pair(Array(n) { block().first }, Array(n) { block().second }) +} + +inline fun recursive( + inlineOptions(ONLY_LOCAL_RETURN) block: () -> R +): Pair, Array> { + return createArray(5) { Pair(block(), block()) } +} + +fun box(): String { + val y = createArray(5) { Pair(1, "test") } + val x = recursive(){ "abc" } + + assert(y.first.all { it == 1 } ) + assert(y.second.all { it == "test" }) + assert(x.first.all { it == "abc" }) + assert(x.second.all { it == "abc" }) + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index a746aa75acf..ac0def4157a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -30,7 +30,7 @@ import java.util.regex.Pattern; @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithStdlib") @TestDataPath("$PROJECT_ROOT") -@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class}) +@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Reified.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class}) @RunWith(JUnit3RunnerWithInners.class) public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithStdlib() throws Exception { @@ -2412,6 +2412,33 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode } } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/reified") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Reified extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInReified() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reified"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("newArrayInt.kt") + public void testNewArrayInt() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/newArrayInt.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("recursiveNewArray.kt") + public void testRecursiveNewArray() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/recursiveNewArray.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("sameIndexRecursive.kt") + public void testSameIndexRecursive() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/sameIndexRecursive.kt"); + doTestWithStdlib(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/storeStackBeforeInline") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java index ea8d8b8797a..f8494eb6373 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java @@ -102,6 +102,14 @@ public class Intrinsics { "throwParameterIsNullException" )); + private static void throwUndefinedForReified() { + throw new UnsupportedOperationException("You should not use functions with reified parameter without inline"); + } + + public static void reifyNewArray(int parameterTypeIndex) { + throwUndefinedForReified(); + } + public static T sanitizeStackTrace(T throwable) { StackTraceElement[] stackTrace = throwable.getStackTrace(); ArrayList list = new ArrayList(stackTrace.length);