Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlin support #402

Open
Pear0 opened this issue Jan 14, 2017 · 4 comments
Open

Kotlin support #402

Pear0 opened this issue Jan 14, 2017 · 4 comments

Comments

@Pear0
Copy link
Contributor

Pear0 commented Jan 14, 2017

Kotlin support would be great and nearly works but Kotlin relies on kotlin/Intrinsics and other stdlib classes for many operations that it performs.

Even the most basic RobotPlayer will be rejected by the instrumenter because Kotlin inserts non-null checks using Intrinsics.requireNonNull.

@file:JvmName("RobotPlayer")

package kotlin_test

import battlecode.common.RobotController

fun run(rc: RobotController) {
    println("Hello World")
}

These particular checks can be disabled with -Xno-param-assertions and -Xno-call-assertions, but Kotlin relies on its stdlib for all kinds of things which can't be disabled.

fun check(x: String?) {
    val y = x!! // inserts call to Intrinsics.throwNpe()
    ...
}
fun listOperations() {
    val a = 1..6 // references kotlin/ranges/IntRange
    val b = a.map { it * 2 } // references kotlin/collections/CollectionsKt
}

I'm using Kotlin 1.0.6 if that matters.

@HalfVoxel
Copy link
Contributor

See also http://battlecodeforum.org/t/anyone-interested-in-kotlin/134

Regarding the nonNull checks and similar things, it would be great if the instrumenter specifically made such assertions have a 0 cost to avoid penalizing bots just based on the language used even if the algorithms are exactly the same.

@Pear0
Copy link
Contributor Author

Pear0 commented Jan 16, 2017

Because of Kotlin's pretty extensive interop features, the only thing needed to get it working should be allowing kotlin's stdlib packages.

I agree with @HalfVoxel though, Intrinsics should probably be ignored bytecode-wise, and possibly Typeintrinsics too.

I'll make a pull request for this if one of the project members weighs in on whether to count Intrinsics.

@kazimuth
Copy link
Contributor

@Pear0 That would be great. Intrinsics should definitely be free. kotlin.reflect should be disabled, unfortunately; this prevents doing things like ::method, but is the best way to do things safely without exposing too many new attack surfaces on the battlecode infrastructure. We can loosen the restrictions once we've audited kotlin.reflect, but I at least don't have enough time to do that right now :/

I'm sorry this feature has taken so long, we've been busy putting out other fires.

@Pear0
Copy link
Contributor Author

Pear0 commented Jan 18, 2017

Some things I've found:

As it turns out, because Kotlin targets 1.6, it doesn't use invokedynamic. It generates inner class wrappers for method and constructor references so ::Random and String::equals. (they still don't work because they reference interfaces in kotlin/reflect)

Disallowing kotlin/reflect also has the side-effect of disabling delegators which rely on kotlin/reflect/KProperty.

@Pear0 Pear0 mentioned this issue Jan 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants