[Wasm][Stdlib] Add public APIs for linear memory access

Needed for interop with APIs that use linear memory.
This commit is contained in:
Svyatoslav Kuzmich
2022-12-29 19:25:23 +00:00
committed by Space Team
parent fbf06b5495
commit 9bc6b420a9
20 changed files with 702 additions and 56 deletions
@@ -211,7 +211,6 @@ class WasmSymbols(
val nullableDoubleIeee754Equals = getInternalFunction("nullableDoubleIeee754Equals")
val unsafeGetScratchRawMemory = getInternalFunction("unsafeGetScratchRawMemory")
val unsafeGetScratchRawMemorySize = getInternalFunction("unsafeGetScratchRawMemorySize")
val startCoroutineUninterceptedOrReturnIntrinsics =
(0..2).map { getInternalFunction("startCoroutineUninterceptedOrReturnIntrinsic$it") }
@@ -568,15 +568,9 @@ class BodyGenerator(
}
wasmSymbols.unsafeGetScratchRawMemory -> {
// TODO: This drops size of the allocated segment. Instead we can check that it's in bounds for better error messages.
body.buildDrop()
body.buildConstI32Symbol(context.scratchMemAddr)
}
wasmSymbols.unsafeGetScratchRawMemorySize -> {
body.buildConstI32Symbol(WasmSymbol(context.scratchMemSizeInBytes))
}
wasmSymbols.wasmArrayCopy -> {
val immediate = WasmImmediate.GcType(
context.referenceGcType(call.getTypeArgument(0)!!.getRuntimeClass(irBuiltIns).symbol)
@@ -891,6 +885,8 @@ class BodyGenerator(
WasmImmediate.HeapType(WasmHeapType.Type(getReferenceGcType()))
WasmImmediateKind.TYPE_IDX ->
WasmImmediate.TypeIdx(getReferenceGcType())
WasmImmediateKind.MEMORY_IDX ->
WasmImmediate.MemoryIdx(0)
else ->
error("Immediate $imm is unsupported")
@@ -65,7 +65,6 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
val initFunctions = mutableListOf<FunWithPriority>()
val scratchMemAddr = WasmSymbol<Int>()
val scratchMemSizeInBytes = 65_536
val stringPoolSize = WasmSymbol<Int>()
@@ -127,11 +126,8 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
currentDataSectionAddress += typeInfoElement.sizeInBytes
}
// Reserve some memory to pass complex exported types (like strings). It's going to be accessible through 'unsafeGetScratchRawMemory'
// runtime call from stdlib.
currentDataSectionAddress = alignUp(currentDataSectionAddress, INT_SIZE_BYTES)
scratchMemAddr.bind(currentDataSectionAddress)
currentDataSectionAddress += scratchMemSizeInBytes
bind(classIds.unbound, klassIds)
interfaceId.unbound.onEachIndexed { index, entry -> entry.value.bind(index) }
@@ -176,9 +172,10 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
val typeInfoSize = currentDataSectionAddress
val memorySizeInPages = (typeInfoSize / 65_536) + 1
val memory = WasmMemory(WasmLimits(memorySizeInPages.toUInt(), memorySizeInPages.toUInt()))
val memory = WasmMemory(WasmLimits(memorySizeInPages.toUInt(), null /* "unlimited" */))
// Need to export the memory in order to pass complex objects to the host language.
// Export name "memory" is a WASI ABI convention.
exports += WasmExport.Memory("memory", memory)
val importedFunctions = functions.elements.filterIsInstance<WasmFunction.Imported>()
@@ -28,9 +28,6 @@ class WasmModuleCodegenContext(
val stringPoolSize: WasmSymbol<Int>
get() = wasmFragment.stringPoolSize
val scratchMemSizeInBytes: Int
get() = wasmFragment.scratchMemSizeInBytes
fun transformType(irType: IrType): WasmType {
return with(typeTransformer) { irType.toWasmValueType() }
}