[Wasm] Replace deprecated cast instructions
This commit is contained in:
committed by
Space Team
parent
45897cf045
commit
6437d0919c
@@ -189,8 +189,8 @@ class WasmSymbols(
|
|||||||
val refEq = getInternalFunction("wasm_ref_eq")
|
val refEq = getInternalFunction("wasm_ref_eq")
|
||||||
val refIsNull = getInternalFunction("wasm_ref_is_null")
|
val refIsNull = getInternalFunction("wasm_ref_is_null")
|
||||||
val externRefIsNull = getInternalFunction("wasm_externref_is_null")
|
val externRefIsNull = getInternalFunction("wasm_externref_is_null")
|
||||||
val refTest = getInternalFunction("wasm_ref_test_deprecated")
|
val refTest = getInternalFunction("wasm_ref_test")
|
||||||
val refCastNull = getInternalFunction("wasm_ref_cast_deprecated")
|
val refCastNull = getInternalFunction("wasm_ref_cast_null")
|
||||||
val wasmArrayCopy = getInternalFunction("wasm_array_copy")
|
val wasmArrayCopy = getInternalFunction("wasm_array_copy")
|
||||||
val wasmArrayNewData0 = getInternalFunction("array_new_data0")
|
val wasmArrayNewData0 = getInternalFunction("array_new_data0")
|
||||||
|
|
||||||
|
|||||||
+26
-8
@@ -435,7 +435,7 @@ class BodyGenerator(
|
|||||||
body.commentGroupStart { "virtual call: ${function.fqNameWhenAvailable}" }
|
body.commentGroupStart { "virtual call: ${function.fqNameWhenAvailable}" }
|
||||||
|
|
||||||
//TODO: check why it could be needed
|
//TODO: check why it could be needed
|
||||||
generateRefNullCast(receiver.type, klass.defaultType, location)
|
generateRefCast(receiver.type, klass.defaultType, location)
|
||||||
|
|
||||||
body.buildStructGet(context.referenceGcType(klass.symbol), WasmSymbol(0), location)
|
body.buildStructGet(context.referenceGcType(klass.symbol), WasmSymbol(0), location)
|
||||||
body.buildStructGet(context.referenceVTableGcType(klass.symbol), WasmSymbol(vfSlot), location)
|
body.buildStructGet(context.referenceVTableGcType(klass.symbol), WasmSymbol(vfSlot), location)
|
||||||
@@ -450,7 +450,7 @@ class BodyGenerator(
|
|||||||
body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1), location)
|
body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1), location)
|
||||||
|
|
||||||
val classITableReference = context.referenceClassITableGcType(symbol)
|
val classITableReference = context.referenceClassITableGcType(symbol)
|
||||||
body.buildRefCastNullStatic(classITableReference, location)
|
body.buildRefCastStatic(classITableReference, location)
|
||||||
body.buildStructGet(classITableReference, context.referenceClassITableInterfaceSlot(symbol), location)
|
body.buildStructGet(classITableReference, context.referenceClassITableInterfaceSlot(symbol), location)
|
||||||
|
|
||||||
val vfSlot = context.getInterfaceMetadata(symbol).methods
|
val vfSlot = context.getInterfaceMetadata(symbol).methods
|
||||||
@@ -486,6 +486,15 @@ class BodyGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun generateRefCast(fromType: IrType, toType: IrType, location: SourceLocation) {
|
||||||
|
if (!isDownCastAlwaysSuccessInRuntime(fromType, toType)) {
|
||||||
|
body.buildRefCastStatic(
|
||||||
|
toType = context.referenceGcType(toType.getRuntimeClass(irBuiltIns).symbol),
|
||||||
|
location
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun generateRefTest(fromType: IrType, toType: IrType, location: SourceLocation) {
|
private fun generateRefTest(fromType: IrType, toType: IrType, location: SourceLocation) {
|
||||||
if (!isDownCastAlwaysSuccessInRuntime(fromType, toType)) {
|
if (!isDownCastAlwaysSuccessInRuntime(fromType, toType)) {
|
||||||
body.buildRefTestStatic(
|
body.buildRefTestStatic(
|
||||||
@@ -537,7 +546,14 @@ class BodyGenerator(
|
|||||||
body.buildBlock("isInterface", WasmRefNullType(WasmHeapType.Simple.Data)) { innerLabel ->
|
body.buildBlock("isInterface", WasmRefNullType(WasmHeapType.Simple.Data)) { innerLabel ->
|
||||||
body.buildGetLocal(parameterLocal, location)
|
body.buildGetLocal(parameterLocal, location)
|
||||||
body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1), location)
|
body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1), location)
|
||||||
body.buildBrInstr(WasmOp.BR_ON_CAST_FAIL_DEPRECATED, innerLabel, classITable, location)
|
|
||||||
|
body.buildBrInstr(
|
||||||
|
WasmOp.BR_ON_CAST_FAIL,
|
||||||
|
innerLabel,
|
||||||
|
classITable,
|
||||||
|
location,
|
||||||
|
)
|
||||||
|
|
||||||
body.buildStructGet(classITable, context.referenceClassITableInterfaceSlot(irInterface.symbol), location)
|
body.buildStructGet(classITable, context.referenceClassITableInterfaceSlot(irInterface.symbol), location)
|
||||||
body.buildInstr(WasmOp.REF_IS_NULL, location)
|
body.buildInstr(WasmOp.REF_IS_NULL, location)
|
||||||
body.buildInstr(WasmOp.I32_EQZ, location)
|
body.buildInstr(WasmOp.I32_EQZ, location)
|
||||||
@@ -581,7 +597,7 @@ class BodyGenerator(
|
|||||||
val klass: IrClass = backendContext.inlineClassesUtils.getInlinedClass(toType)!!
|
val klass: IrClass = backendContext.inlineClassesUtils.getInlinedClass(toType)!!
|
||||||
val field = getInlineClassBackingField(klass)
|
val field = getInlineClassBackingField(klass)
|
||||||
|
|
||||||
generateRefNullCast(fromType, toType, location)
|
generateRefCast(fromType, toType, location)
|
||||||
generateInstanceFieldAccess(field, location)
|
generateInstanceFieldAccess(field, location)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,15 +609,17 @@ class BodyGenerator(
|
|||||||
body.buildBlock("returnIfAny", WasmAnyRef) { innerLabel ->
|
body.buildBlock("returnIfAny", WasmAnyRef) { innerLabel ->
|
||||||
body.buildGetLocal(functionContext.referenceLocal(0), location)
|
body.buildGetLocal(functionContext.referenceLocal(0), location)
|
||||||
body.buildInstr(WasmOp.EXTERN_INTERNALIZE, location)
|
body.buildInstr(WasmOp.EXTERN_INTERNALIZE, location)
|
||||||
body.buildBrInstr(WasmOp.BR_ON_NON_DATA_DEPRECATED, innerLabel, location)
|
|
||||||
body.buildBrInstr(
|
body.buildBrInstr(
|
||||||
WasmOp.BR_ON_CAST_FAIL_DEPRECATED,
|
WasmOp.BR_ON_CAST_FAIL,
|
||||||
innerLabel,
|
innerLabel,
|
||||||
context.referenceGcType(backendContext.irBuiltIns.anyClass),
|
context.referenceGcType(backendContext.irBuiltIns.anyClass),
|
||||||
location
|
location,
|
||||||
)
|
)
|
||||||
|
|
||||||
body.buildInstr(WasmOp.RETURN, location)
|
body.buildInstr(WasmOp.RETURN, location)
|
||||||
}
|
}
|
||||||
|
body.buildDrop(location)
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmSymbols.wasmArrayCopy -> {
|
wasmSymbols.wasmArrayCopy -> {
|
||||||
@@ -770,7 +788,7 @@ class BodyGenerator(
|
|||||||
// REF -> REF -> REF_CAST
|
// REF -> REF -> REF_CAST
|
||||||
if (!expectedIsPrimitive) {
|
if (!expectedIsPrimitive) {
|
||||||
if (expectedClassErased.isSubclassOf(actualClassErased)) {
|
if (expectedClassErased.isSubclassOf(actualClassErased)) {
|
||||||
generateRefNullCast(actualTypeErased, expectedTypeErased, location)
|
generateRefCast(actualTypeErased, expectedTypeErased, location)
|
||||||
} else {
|
} else {
|
||||||
body.buildUnreachableForVerifier()
|
body.buildUnreachableForVerifier()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ internal fun isNullish(ref: ExternalInterfaceType?): Boolean =
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
internal fun returnArgumentIfItIsKotlinAny(ref: ExternalInterfaceType): Unit = implementedAsIntrinsic
|
internal fun returnArgumentIfItIsKotlinAny(): Unit = implementedAsIntrinsic
|
||||||
|
|
||||||
internal fun externRefToAny(ref: ExternalInterfaceType): Any? {
|
internal fun externRefToAny(ref: ExternalInterfaceType): Any? {
|
||||||
// TODO rewrite it so to get something like:
|
// TODO rewrite it so to get something like:
|
||||||
@@ -169,7 +169,7 @@ internal fun externRefToAny(ref: ExternalInterfaceType): Any? {
|
|||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// If ref is an instance of kotlin class -- return it casted to Any
|
// If ref is an instance of kotlin class -- return it casted to Any
|
||||||
returnArgumentIfItIsKotlinAny(ref)
|
returnArgumentIfItIsKotlinAny()
|
||||||
|
|
||||||
// If we have Null in notNullRef -- return null
|
// If we have Null in notNullRef -- return null
|
||||||
// If we already have a box -- return it,
|
// If we already have a box -- return it,
|
||||||
|
|||||||
@@ -20,11 +20,16 @@ internal fun wasm_unreachable(): Nothing =
|
|||||||
implementedAsIntrinsic
|
implementedAsIntrinsic
|
||||||
|
|
||||||
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
|
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
|
||||||
internal fun <reified To> wasm_ref_cast_deprecated(a: Any?): To =
|
internal fun <reified To> wasm_ref_cast_null(a: Any?): To =
|
||||||
implementedAsIntrinsic
|
implementedAsIntrinsic
|
||||||
|
|
||||||
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
|
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
|
||||||
internal fun <reified To> wasm_ref_test_deprecated(a: Any?): Boolean =
|
internal fun <reified To> wasm_ref_test(a: Any?): Boolean =
|
||||||
|
implementedAsIntrinsic
|
||||||
|
|
||||||
|
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
|
||||||
|
@WasmOp(WasmOp.REF_TEST_NULL)
|
||||||
|
internal fun <reified To> wasm_ref_test_null(a: Any?): Boolean =
|
||||||
implementedAsIntrinsic
|
implementedAsIntrinsic
|
||||||
|
|
||||||
internal fun <T> wasm_array_copy(destination: T, destinationIndex: Int, source: T, sourceIndex: Int, length: Int): Unit =
|
internal fun <T> wasm_array_copy(destination: T, destinationIndex: Int, source: T, sourceIndex: Int, length: Int): Unit =
|
||||||
|
|||||||
@@ -247,12 +247,14 @@ internal annotation class WasmOp(val name: String) {
|
|||||||
const val I31_GET_S = "I31_GET_S"
|
const val I31_GET_S = "I31_GET_S"
|
||||||
const val I31_GET_U = "I31_GET_U"
|
const val I31_GET_U = "I31_GET_U"
|
||||||
const val REF_EQ = "REF_EQ"
|
const val REF_EQ = "REF_EQ"
|
||||||
|
const val REF_TEST = "REF_TEST"
|
||||||
|
const val REF_TEST_NULL = "REF_TEST_NULL"
|
||||||
|
const val REF_CAST = "REF_CAST"
|
||||||
|
const val REF_CAST_NULL = "REF_CAST_NULL"
|
||||||
|
const val BR_ON_CAST = "BR_ON_CAST"
|
||||||
|
const val BR_ON_CAST_FAIL = "BR_ON_CAST_FAIL"
|
||||||
const val EXTERN_INTERNALIZE = "EXTERN_INTERNALIZE"
|
const val EXTERN_INTERNALIZE = "EXTERN_INTERNALIZE"
|
||||||
const val EXTERN_EXTERNALIZE = "EXTERN_EXTERNALIZE"
|
const val EXTERN_EXTERNALIZE = "EXTERN_EXTERNALIZE"
|
||||||
const val REF_TEST_DEPRECATED = "REF_TEST_DEPRECATED"
|
|
||||||
const val REF_CAST_DEPRECATED = "REF_CAST_DEPRECATED"
|
|
||||||
const val BR_ON_CAST_FAIL_DEPRECATED = "BR_ON_CAST_FAIL_DEPRECATED"
|
|
||||||
const val BR_ON_NON_DATA_DEPRECATED = "BR_ON_NON_DATA_DEPRECATED"
|
|
||||||
const val GET_UNIT = "GET_UNIT"
|
const val GET_UNIT = "GET_UNIT"
|
||||||
const val PSEUDO_COMMENT_PREVIOUS_INSTR = "PSEUDO_COMMENT_PREVIOUS_INSTR"
|
const val PSEUDO_COMMENT_PREVIOUS_INSTR = "PSEUDO_COMMENT_PREVIOUS_INSTR"
|
||||||
const val PSEUDO_COMMENT_GROUP_START = "PSEUDO_COMMENT_GROUP_START"
|
const val PSEUDO_COMMENT_GROUP_START = "PSEUDO_COMMENT_GROUP_START"
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ public fun <T : Any> T.toJsReference(): JsReference<T> =
|
|||||||
|
|
||||||
/** Retrieve original Kotlin value from JsReference */
|
/** Retrieve original Kotlin value from JsReference */
|
||||||
public fun <T : Any> JsReference<T>.get(): T {
|
public fun <T : Any> JsReference<T>.get(): T {
|
||||||
returnArgumentIfItIsKotlinAny(this)
|
returnArgumentIfItIsKotlinAny()
|
||||||
throw ClassCastException("JsReference doesn't contain a Kotlin type")
|
throw ClassCastException("JsReference doesn't contain a Kotlin type")
|
||||||
}
|
}
|
||||||
@@ -374,32 +374,17 @@ enum class WasmOp(
|
|||||||
I31_GET_U("i31.get_u", 0xFB_22),
|
I31_GET_U("i31.get_u", 0xFB_22),
|
||||||
|
|
||||||
REF_EQ("ref.eq", 0xD5),
|
REF_EQ("ref.eq", 0xD5),
|
||||||
// Not yet supported by Binaryen
|
REF_TEST("ref.test", 0xFB_40, HEAP_TYPE),
|
||||||
// REF_TEST("ref.test", 0xFB_40, HEAP_TYPE),
|
REF_TEST_NULL("ref.test null", 0xFB_48, HEAP_TYPE),
|
||||||
// REF_TEST_NULL("ref.test null", 0xFB_48, HEAP_TYPE),
|
REF_CAST("ref.cast", 0xFB_41, HEAP_TYPE),
|
||||||
// REF_CAST("ref.cast", 0xFB_41, HEAP_TYPE),
|
REF_CAST_NULL("ref.cast null", 0xFB_49, HEAP_TYPE),
|
||||||
// REF_CAST_NULL("ref.cast null", 0xFB_49, HEAP_TYPE),
|
|
||||||
|
|
||||||
// Not yet supported by V8
|
BR_ON_CAST("br_on_cast", 0xFB_42, listOf(LABEL_IDX, HEAP_TYPE)),
|
||||||
// BR_ON_CAST("br_on_cast", 0xFB42, listOf(LABEL_IDX, HEAP_TYPE)),
|
BR_ON_CAST_FAIL("br_on_cast_fail", 0xFB_43, listOf(LABEL_IDX, HEAP_TYPE)),
|
||||||
// BR_ON_CAST_NULL("br_on_cast null", 0xFB4A, listOf(LABEL_IDX, HEAP_TYPE)),
|
|
||||||
// BR_ON_CAST_FAIL("br_on_cast_fail", 0xFB43, listOf(LABEL_IDX, HEAP_TYPE)),
|
|
||||||
// BR_ON_CAST_FAIL_NULL("br_on_cast_fail null", 0xFB4B, listOf(LABEL_IDX, HEAP_TYPE)),
|
|
||||||
|
|
||||||
EXTERN_INTERNALIZE("extern.internalize", 0xfb70), // externref -> anyref
|
EXTERN_INTERNALIZE("extern.internalize", 0xfb70), // externref -> anyref
|
||||||
EXTERN_EXTERNALIZE("extern.externalize", 0xfb71), // anyref -> externref
|
EXTERN_EXTERNALIZE("extern.externalize", 0xfb71), // anyref -> externref
|
||||||
|
|
||||||
// ------------------------
|
|
||||||
// Deprecated instructions
|
|
||||||
// TODO Remove as soon as V8 & Binaryen support new instructions.
|
|
||||||
// Revert 7f8f7aa0.
|
|
||||||
|
|
||||||
REF_TEST_DEPRECATED("ref.test", 0xFB_44, STRUCT_TYPE_IDX),
|
|
||||||
REF_CAST_DEPRECATED("ref.cast", 0xFB_45, STRUCT_TYPE_IDX),
|
|
||||||
|
|
||||||
BR_ON_CAST_FAIL_DEPRECATED("br_on_cast_fail", 0xFB_47, listOf(LABEL_IDX, STRUCT_TYPE_IDX)),
|
|
||||||
BR_ON_NON_DATA_DEPRECATED("br_on_non_data_fail", 0xFB_64, listOf(LABEL_IDX)),
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Pseudo-instruction, just alias for a normal call. It's used to easily spot get_unit on the wasm level.
|
// Pseudo-instruction, just alias for a normal call. It's used to easily spot get_unit on the wasm level.
|
||||||
GET_UNIT("call", 0x10, FUNC_IDX),
|
GET_UNIT("call", 0x10, FUNC_IDX),
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ abstract class WasmExpressionBuilder {
|
|||||||
fun buildBrInstr(brOp: WasmOp, absoluteBlockLevel: Int, symbol: WasmSymbolReadOnly<WasmTypeDeclaration>, location: SourceLocation) {
|
fun buildBrInstr(brOp: WasmOp, absoluteBlockLevel: Int, symbol: WasmSymbolReadOnly<WasmTypeDeclaration>, location: SourceLocation) {
|
||||||
val relativeLevel = numberOfNestedBlocks - absoluteBlockLevel
|
val relativeLevel = numberOfNestedBlocks - absoluteBlockLevel
|
||||||
assert(relativeLevel >= 0) { "Negative relative block index" }
|
assert(relativeLevel >= 0) { "Negative relative block index" }
|
||||||
buildInstr(brOp, location, WasmImmediate.LabelIdx(relativeLevel), WasmImmediate.TypeIdx(symbol))
|
buildInstr(brOp, location, WasmImmediate.LabelIdx(relativeLevel), WasmImmediate.HeapType(WasmHeapType.Type(symbol)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildBr(absoluteBlockLevel: Int, location: SourceLocation) {
|
fun buildBr(absoluteBlockLevel: Int, location: SourceLocation) {
|
||||||
@@ -179,11 +179,15 @@ abstract class WasmExpressionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun buildRefCastNullStatic(toType: WasmSymbolReadOnly<WasmTypeDeclaration>, location: SourceLocation) {
|
fun buildRefCastNullStatic(toType: WasmSymbolReadOnly<WasmTypeDeclaration>, location: SourceLocation) {
|
||||||
buildInstr(WasmOp.REF_CAST_DEPRECATED, location, WasmImmediate.TypeIdx(toType))
|
buildInstr(WasmOp.REF_CAST_NULL, location, WasmImmediate.HeapType(WasmHeapType.Type(toType)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildRefCastStatic(toType: WasmSymbolReadOnly<WasmTypeDeclaration>, location: SourceLocation) {
|
||||||
|
buildInstr(WasmOp.REF_CAST, location, WasmImmediate.HeapType(WasmHeapType.Type(toType)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildRefTestStatic(toType: WasmSymbolReadOnly<WasmTypeDeclaration>, location: SourceLocation) {
|
fun buildRefTestStatic(toType: WasmSymbolReadOnly<WasmTypeDeclaration>, location: SourceLocation) {
|
||||||
buildInstr(WasmOp.REF_TEST_DEPRECATED, location, WasmImmediate.TypeIdx(toType))
|
buildInstr(WasmOp.REF_TEST, location, WasmImmediate.HeapType(WasmHeapType.Type(toType)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildRefNull(type: WasmHeapType, location: SourceLocation) {
|
fun buildRefNull(type: WasmHeapType, location: SourceLocation) {
|
||||||
|
|||||||
Reference in New Issue
Block a user