Wasm/Interpret/FunctionTable.cs
using System.Collections.Generic;
namespace WasmBox.Wasm.Interpret {
/// <summary>
/// Defines a table of function values.
/// </summary>
public sealed class FunctionTable {
/// <summary>
/// Creates a function table from the given resizable limits.
/// The table's initial contents are trap values.
/// </summary>
/// <param name="limits">The table's limits.</param>
public FunctionTable(ResizableLimits limits) {
this.Limits = limits;
this.contents = new List<FunctionDefinition>((int)limits.Initial);
var funcDef = new ThrowFunctionDefinition(
new WasmValueType[0],
new WasmValueType[0],
new TrapException("Indirect call target not initialized yet.", TrapException.SpecMessages.UninitializedElement));
for (int i = 0; i < limits.Initial; i++) {
contents.Add(funcDef);
}
}
/// <summary>
/// Gets this function table's limits.
/// </summary>
/// <returns>The function table's limits.</returns>
public ResizableLimits Limits { get; private set; }
private List<FunctionDefinition> contents;
/// <summary>
/// Gets or sets the function definition at the given index in the table.
/// </summary>
public FunctionDefinition this[uint index] {
get {
CheckBounds(index);
return contents[(int)index];
}
set {
CheckBounds(index);
contents[(int)index] = value;
}
}
private void CheckBounds(uint index) {
if (index >= contents.Count) {
throw new TrapException(
$"Cannot access element with index {index} in a function table of size {contents.Count}.",
TrapException.SpecMessages.UndefinedElement);
}
}
/// <summary>
/// Gets the number of elements in the table.
/// </summary>
/// <returns>An element count.</returns>
public int Count => contents.Count;
}
}