Skip to content

Kotlin support #402

Open
Open

Description

@Pear0

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.

Activity

  1. HalfVoxel commented on Jan 14, 2017

    @HalfVoxel
    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.

  2. Pear0 commented on Jan 16, 2017

    @Pear0
    ContributorAuthor

    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.

  3. kazimuth commented on Jan 17, 2017

    @kazimuth
    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.

  4. Pear0 commented on Jan 18, 2017

    @Pear0
    ContributorAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions