Support native top-level functions
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.jet.codegen.bridges.Bridge;
|
|||||||
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
|
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
|
||||||
import org.jetbrains.jet.codegen.context.CodegenContext;
|
import org.jetbrains.jet.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.jet.codegen.context.MethodContext;
|
import org.jetbrains.jet.codegen.context.MethodContext;
|
||||||
|
import org.jetbrains.jet.codegen.context.PackageContext;
|
||||||
import org.jetbrains.jet.codegen.context.PackageFacadeContext;
|
import org.jetbrains.jet.codegen.context.PackageFacadeContext;
|
||||||
import org.jetbrains.jet.codegen.optimization.OptimizationMethodVisitor;
|
import org.jetbrains.jet.codegen.optimization.OptimizationMethodVisitor;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
@@ -132,6 +133,10 @@ public class FunctionCodegen extends ParentCodegenAware {
|
|||||||
int flags = getMethodAsmFlags(functionDescriptor, methodContextKind);
|
int flags = getMethodAsmFlags(functionDescriptor, methodContextKind);
|
||||||
boolean isNative = NativeDeclarationsPackage.hasNativeAnnotation(functionDescriptor);
|
boolean isNative = NativeDeclarationsPackage.hasNativeAnnotation(functionDescriptor);
|
||||||
|
|
||||||
|
if (isNative && owner instanceof PackageContext && !(owner instanceof PackageFacadeContext)) {
|
||||||
|
// Native methods are only defined in package facades and do not need package part implementations
|
||||||
|
return;
|
||||||
|
}
|
||||||
MethodVisitor mv = v.newMethod(origin,
|
MethodVisitor mv = v.newMethod(origin,
|
||||||
flags,
|
flags,
|
||||||
asmMethod.getName(),
|
asmMethod.getName(),
|
||||||
@@ -158,7 +163,6 @@ public class FunctionCodegen extends ParentCodegenAware {
|
|||||||
generateBridges(functionDescriptor);
|
generateBridges(functionDescriptor);
|
||||||
|
|
||||||
boolean staticInClassObject = AnnotationsPackage.isPlatformStaticInClassObject(functionDescriptor);
|
boolean staticInClassObject = AnnotationsPackage.isPlatformStaticInClassObject(functionDescriptor);
|
||||||
|
|
||||||
if (staticInClassObject) {
|
if (staticInClassObject) {
|
||||||
MemberCodegen<?> codegen = getParentCodegen().getParentCodegen();
|
MemberCodegen<?> codegen = getParentCodegen().getParentCodegen();
|
||||||
((ImplementationBodyCodegen) codegen).addAdditionalTask(new PlatformStaticGenerator(functionDescriptor, origin, state));
|
((ImplementationBodyCodegen) codegen).addAdditionalTask(new PlatformStaticGenerator(functionDescriptor, origin, state));
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignat
|
|||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
|
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
|
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.nativeDeclarations.NativeDeclarationsPackage;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||||
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
|
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
|
||||||
@@ -110,10 +111,11 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||||
if (container instanceof PackageFragmentDescriptor) {
|
if (container instanceof PackageFragmentDescriptor) {
|
||||||
|
boolean effectiveInsideModule = isInsideModule && !NativeDeclarationsPackage.hasNativeAnnotation(descriptor);
|
||||||
return Type.getObjectType(internalNameForPackage(
|
return Type.getObjectType(internalNameForPackage(
|
||||||
(PackageFragmentDescriptor) container,
|
(PackageFragmentDescriptor) container,
|
||||||
(CallableMemberDescriptor) descriptor,
|
(CallableMemberDescriptor) descriptor,
|
||||||
isInsideModule
|
effectiveInsideModule
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else if (container instanceof ClassDescriptor) {
|
else if (container instanceof ClassDescriptor) {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ object ObjWithNative {
|
|||||||
platformStatic native fun bar(l: Long, s: String = ""): Double
|
platformStatic native fun bar(l: Long, s: String = ""): Double
|
||||||
}
|
}
|
||||||
|
|
||||||
|
native fun topLevel(x: Int = 1): Double
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var d = 0.0
|
var d = 0.0
|
||||||
|
|
||||||
@@ -27,5 +29,13 @@ fun box(): String {
|
|||||||
catch (e: java.lang.UnsatisfiedLinkError) {
|
catch (e: java.lang.UnsatisfiedLinkError) {
|
||||||
if (e.getMessage() != "foo.ObjWithNative.foo(I)D") return "Fail 2: " + e.getMessage()
|
if (e.getMessage() != "foo.ObjWithNative.foo(I)D") return "Fail 2: " + e.getMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
d = topLevel()
|
||||||
|
return "Link error expected on object"
|
||||||
|
}
|
||||||
|
catch (e: java.lang.UnsatisfiedLinkError) {
|
||||||
|
if (e.getMessage() != "foo.FooPackage.topLevel(I)D") return "Fail 3: " + e.getMessage()
|
||||||
|
}
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import kotlin.jvm.*
|
||||||
|
import kotlin.platform.*
|
||||||
|
|
||||||
|
native fun bar(l: Long, s: String): Double
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var d = 0.0
|
||||||
|
|
||||||
|
try {
|
||||||
|
d = bar(1, "")
|
||||||
|
return "Link error expected on object"
|
||||||
|
}
|
||||||
|
catch (e: java.lang.UnsatisfiedLinkError) {
|
||||||
|
if (e.getMessage() != "foo.FooPackage.bar(JLjava/lang/String;)D") return "Fail 1: " + e.getMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -1836,6 +1836,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/native/staticNative.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/native/staticNative.kt");
|
||||||
doTestWithStdlib(fileName);
|
doTestWithStdlib(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("topLevel.kt")
|
||||||
|
public void testTopLevel() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/native/topLevel.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/nonLocalReturns")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/nonLocalReturns")
|
||||||
|
|||||||
Reference in New Issue
Block a user