Skip to content

Commit

Permalink
Add @SharedImmutable from K/N to some global declarations in JSON par…
Browse files Browse the repository at this point in the history
…ser, so it is now accessible from multiple workers

Fixes #225
  • Loading branch information
sandwwraith committed Sep 28, 2018
1 parent b24f0fb commit 7a7ebe9
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 27 deletions.
6 changes: 6 additions & 0 deletions json/common/src/kotlinx/serialization/PlaformParts.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kotlinx.serialization

@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@UseExperimental(ExperimentalMultiplatform::class)
@OptionalExpectation
expect annotation class SharedImmutable()
61 changes: 34 additions & 27 deletions json/common/src/kotlinx/serialization/json/JsonParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package kotlinx.serialization.json

import kotlinx.serialization.SharedImmutable
import kotlinx.serialization.json.EscapeCharMappings.ESC2C

// special strings
internal const val NULL = "null"

Expand Down Expand Up @@ -50,7 +53,12 @@ internal const val TC_EOF: Byte = 12
// mapping from chars to token classes
private const val CTC_MAX = 0x7e

private val C2TC = ByteArray(CTC_MAX).apply {
// mapping from escape chars real chars
private const val C2ESC_MAX = 0x5d
private const val ESC2C_MAX = 0x75

@SharedImmutable
internal val C2TC = ByteArray(CTC_MAX).apply {
for (i in 0..0x20)
initC2TC(i, TC_INVALID)
initC2TC(0x09, TC_WS)
Expand All @@ -67,6 +75,31 @@ private val C2TC = ByteArray(CTC_MAX).apply {
initC2TC(STRING_ESC, TC_STRING_ESC)
}

// object instead of @SharedImmutable because there is mutual initialization in [initC2ESC]
internal object EscapeCharMappings {
internal val ESC2C = CharArray(ESC2C_MAX)

internal val C2ESC = CharArray(C2ESC_MAX).apply {
for (i in 0x00..0x1f)
initC2ESC(i, UNICODE_ESC)
initC2ESC(0x08, 'b')
initC2ESC(0x09, 't')
initC2ESC(0x0a, 'n')
initC2ESC(0x0c, 'f')
initC2ESC(0x0d, 'r')
initC2ESC('/', '/')
initC2ESC(STRING, STRING)
initC2ESC(STRING_ESC, STRING_ESC)
}

private fun CharArray.initC2ESC(c: Int, esc: Char) {
this[c] = esc
if (esc != UNICODE_ESC) ESC2C[esc.toInt()] = c.toChar()
}

private fun CharArray.initC2ESC(c: Char, esc: Char) = initC2ESC(c.toInt(), esc)
}

private fun ByteArray.initC2TC(c: Int, cl: Byte) {
this[c] = cl
}
Expand All @@ -77,32 +110,6 @@ private fun ByteArray.initC2TC(c: Char, cl: Byte) {

internal fun charToTokenClass(c: Char) = if (c.toInt() < CTC_MAX) C2TC[c.toInt()] else TC_OTHER

// mapping from escape chars real chars
private const val C2ESC_MAX = 0x5d
private const val ESC2C_MAX = 0x75

private val ESC2C = CharArray(ESC2C_MAX)

private val C2ESC = CharArray(C2ESC_MAX).apply {
for (i in 0x00..0x1f)
initC2ESC(i, UNICODE_ESC)
initC2ESC(0x08, 'b')
initC2ESC(0x09, 't')
initC2ESC(0x0a, 'n')
initC2ESC(0x0c, 'f')
initC2ESC(0x0d, 'r')
initC2ESC('/', '/')
initC2ESC(STRING, STRING)
initC2ESC(STRING_ESC, STRING_ESC)
}

private fun CharArray.initC2ESC(c: Int, esc: Char) {
this[c] = esc
if (esc != UNICODE_ESC) ESC2C[esc.toInt()] = c.toChar()
}

private fun CharArray.initC2ESC(c: Char, esc: Char) = initC2ESC(c.toInt(), esc)

internal fun escapeToChar(c: Int): Char = if (c < ESC2C_MAX) ESC2C[c] else INVALID


Expand Down
3 changes: 3 additions & 0 deletions json/common/src/kotlinx/serialization/json/StringOps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package kotlinx.serialization.json

import kotlinx.serialization.SharedImmutable

private fun toHexChar(i: Int) : Char {
val d = i and 0xf
return if (d < 10) (d + '0'.toInt()).toChar()
Expand All @@ -26,6 +28,7 @@ private fun toHexChar(i: Int) : Char {
* Even though the actual size of this array is 92, it has to be the power of two, otherwise
* JVM cannot perform advanced range-check elimination and vectorization in printQuoted
*/
@SharedImmutable
private val ESCAPE_CHARS: Array<String?> = arrayOfNulls<String>(128).apply {
for (c in 0..0x1f) {
val c1 = toHexChar(c shr 12)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@ actual fun getSerialId(desc: KSerialClassDesc, index: Int): Int? {
}

actual fun getSerialTag(desc: KSerialClassDesc, index: Int): String? = index.toString()

actual typealias SharedImmutable = kotlin.native.SharedImmutable

0 comments on commit 7a7ebe9

Please sign in to comment.