blob: ada573ee6ff63e96abc4913491fe6270b6f6baad [file] [log] [blame]
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.js
internal typealias BitMask = IntArray
private fun bitMaskWith(activeBit: Int): BitMask {
val intArray = IntArray((activeBit shr 5) + 1)
val numberIndex = activeBit shr 5
val positionInNumber = activeBit and 31
val numberWithSettledBit = 1 shl positionInNumber
intArray[numberIndex] = intArray[numberIndex] or numberWithSettledBit
return intArray
}
internal fun BitMask.isBitSet(possibleActiveBit: Int): Boolean {
val numberIndex = possibleActiveBit shr 5
if (numberIndex > size) return false
val positionInNumber = possibleActiveBit and 31
val numberWithSettledBit = 1 shl positionInNumber
return get(numberIndex) and numberWithSettledBit != 0
}
private fun compositeBitMask(capacity: Int, masks: Array<BitMask>): BitMask {
return IntArray(capacity) { i ->
var result = 0
for (mask in masks) {
if (i < mask.size) {
result = result or mask[i]
}
}
result
}
}
internal fun implement(interfaces: Array<dynamic>): BitMask {
var maxSize = 1
val masks = js("[]")
for (i in interfaces) {
var currentSize = maxSize
val imask: BitMask? = i.prototype.`$imask$` ?: i.`$imask$`
if (imask != null) {
masks.push(imask)
currentSize = imask.size
}
val iid: Int? = i.`$metadata$`.iid
val iidImask: BitMask? = iid?.let { bitMaskWith(it) }
if (iidImask != null) {
masks.push(iidImask)
currentSize = JsMath.max(currentSize, iidImask.size)
}
if (currentSize > maxSize) {
maxSize = currentSize
}
}
return compositeBitMask(maxSize, masks)
}