# 数组示例
¥Arrays example
展示如何交换和使用在 WebAssembly 或 JavaScript 中创建的数组。
¥Shows how to exchange and work with arrays either created in WebAssembly or in JavaScript.
# 内容
¥Contents
使用加载器和完整的运行时来处理托管对象。
¥Using the loader and the full runtime to work with managed objects.
在 WebAssembly 中创建数组并在 JavaScript 中使用它们。
¥Creating arrays in WebAssembly and using them in JavaScript.
在 JavaScript 中创建数组并在 WebAssembly 中使用它们。
¥Creating arrays in JavaScript and using them in WebAssembly.
使用数组的副本和实时视图。
¥Using both copies of and live views on arrays.
在数组长度已知的情况下执行
unchecked
访问。¥Performing
unchecked
accesses where the length of an array is known.将对象固定在外部以防止过早的垃圾收集。
¥Pinning objects externally to prevent premature garbage collection.
# 示例
¥Example
#!optimize=speed&runtime=default&exportRuntime
/** Creates a new array and returns it to JavaScript. */
export function createArray(length: i32): Int32Array {
return new Int32Array(length)
}
/** Randomizes the specified array's values. */
export function randomizeArray(arr: Int32Array): void {
for (let i = 0, k = arr.length; i < k; ++i) {
let value = i32((Math.random() * 2.0 - 1.0) * i32.MAX_VALUE)
unchecked(arr[i] = value)
}
}
/** Computes the sum of an array's values and returns the sum to JavaScript. */
export function sumArray(arr: Int32Array): i32 {
let total = 0
for (let i = 0, k = arr.length; i < k; ++i) {
total += unchecked(arr[i])
}
return total
}
// We'll need the unique Int32Array id when allocating one in JavaScript
export const Int32Array_ID = idof<Int32Array>()
#!html
<textarea id="output" style="width: 100%; height: 100%" readonly></textarea>
<script>
loader.instantiate(module_wasm).then(({ exports }) => {
const output = document.getElementById('output')
/** Logs a message to the textarea. */
function log(message = '') {
output.value += `${message}\n`
}
// A simple example using an array created in WebAssembly.
function example1() {
log('=== Example1 ===')
// Obtain the necessary runtime helpers
const { __pin, __unpin, __getArray } = exports
// Create a new array in WebAssembly and get a reference to it. Note that
// the array is not reachable from within WebAssembly, only externally, so
// we should pin it to prevent it from becoming garbage collected too early.
let arrayPtr = __pin(exports.createArray(5))
log(`Array pointer: ${arrayPtr}`)
// Log its elements to make sure these are zero
log('Initial values: ' + __getArray(arrayPtr).join(', '))
// Randomize the array in WebAssembly and log it again
exports.randomizeArray(arrayPtr)
log('Randomized values: ' + __getArray(arrayPtr).join(', '))
// Compute the array values' sum and log it. This will overflow i32 range.
let total = exports.sumArray(arrayPtr)
log(`Sum (likely overflown): ${total}`)
// We are done with the array, so __unpin it so it can become collected.
__unpin(arrayPtr)
log()
}
example1()
// A slightly more advanced example allocating the array in JavaScript instead
// of WebAssembly, and utilizing a live view to modify it in WebAssembly memory.
function example2() {
log('=== Example2 ===')
// Obtain the necessary runtime helpers
const { __pin, __unpin, __newArray, __getArray, __getArrayView } = exports
// Create a new array, but this time in JavaScript. Note that the array is
// again not reachable from within WebAssembly, only externally, so we
// should pin it to prevent it from becoming garbage collected too early.
let arrayPtr = __pin(__newArray(exports.Int32Array_ID, [
3, 4, 5, 6, 7, 8, 9
]))
log('Array pointer: ' + arrayPtr)
// Log its elements to make sure these are the provided values
log('Initial values: ' + __getArray(arrayPtr).join(', '))
// Compute the array values' sum and log it
let total = exports.sumArray(arrayPtr)
log('Sum: ' + total)
// Instead of copying, let's obtain a live view on the array and modify its
// values right in WebAssembly memory.
let view = __getArrayView(arrayPtr)
view.reverse()
// Log the array's elements, now reversed
log('Reversed values: ' + __getArray(arrayPtr).join(', '))
// We are done with the array, so __unpin it so it can become collected.
__unpin(arrayPtr)
log()
}
example2()
})
</script>
注意
此示例利用加载程序来处理托管对象,因此需要设置 --exportRuntime
以向 JavaScript 公开运行时辅助程序。
¥This example utilizes the loader to work with managed objects, hence requires --exportRuntime
to be set to expose the runtime helpers to JavaScript.
# 资源
¥Resources
有关使用加载程序和运行时助手的更多信息可作为 加载器的 和 垃圾收集文档 的一部分获得。
¥Further information on using the loader and the runtime helpers is available as part of the loader's and the garbage collection documentation.