Define a "table" concept.
"Table" is to WebAssembly tables as "Heap" is to WebAssembly linear memories.
This commit is contained in:
@@ -33,3 +33,6 @@ jump_table = EntityRefKind(
|
||||
|
||||
#: A reference to a heap declared in the function preamble.
|
||||
heap = EntityRefKind('heap', 'A heap.')
|
||||
|
||||
#: A reference to a table declared in the function preamble.
|
||||
table = EntityRefKind('table', 'A table.')
|
||||
|
||||
@@ -11,7 +11,7 @@ from cdsl.operands import VALUE, VARIABLE_ARGS
|
||||
from .immediates import imm64, uimm8, uimm32, ieee32, ieee64, offset32
|
||||
from .immediates import boolean, intcc, floatcc, memflags, regunit, trapcode
|
||||
from . import entities
|
||||
from .entities import ebb, sig_ref, func_ref, stack_slot, heap
|
||||
from .entities import ebb, sig_ref, func_ref, stack_slot, heap, table
|
||||
|
||||
Unary = InstructionFormat(VALUE)
|
||||
UnaryImm = InstructionFormat(imm64)
|
||||
@@ -67,6 +67,9 @@ StackStore = InstructionFormat(VALUE, stack_slot, offset32)
|
||||
# Accessing a WebAssembly heap.
|
||||
HeapAddr = InstructionFormat(heap, VALUE, uimm32)
|
||||
|
||||
# Accessing a WebAssembly table.
|
||||
TableAddr = InstructionFormat(table, VALUE, offset32)
|
||||
|
||||
RegMove = InstructionFormat(VALUE, ('src', regunit), ('dst', regunit))
|
||||
CopySpecial = InstructionFormat(('src', regunit), ('dst', regunit))
|
||||
RegSpill = InstructionFormat(
|
||||
|
||||
@@ -221,6 +221,11 @@ call_indirect = Instruction(
|
||||
|
||||
Call the function pointed to by `callee` with the given arguments. The
|
||||
called function must match the specified signature.
|
||||
|
||||
Note that this is different from WebAssembly's ``call_indirect``; the
|
||||
callee is a native address, rather than a table index. For WebAssembly,
|
||||
:inst:`table_addr` and :inst:`load` are used to obtain a native address
|
||||
from a table.
|
||||
""",
|
||||
ins=(SIG, callee, args), outs=rvals, is_call=True)
|
||||
|
||||
@@ -531,6 +536,33 @@ heap_addr = Instruction(
|
||||
""",
|
||||
ins=(H, p, Size), outs=addr)
|
||||
|
||||
#
|
||||
# WebAssembly bounds-checked table accesses.
|
||||
#
|
||||
|
||||
TableOffset = TypeVar('TableOffset', 'An unsigned table offset', ints=(32, 64))
|
||||
|
||||
T = Operand('T', entities.table)
|
||||
p = Operand('p', TableOffset)
|
||||
Offset = Operand('Offset', offset32, 'Byte offset from element address')
|
||||
|
||||
table_addr = Instruction(
|
||||
'table_addr', r"""
|
||||
Bounds check and compute absolute address of a table entry.
|
||||
|
||||
Verify that the offset ``p`` is in bounds for the table T, and generate
|
||||
an absolute address that is safe to dereference.
|
||||
|
||||
``Offset`` must be less than the size of a table element.
|
||||
|
||||
1. If ``p`` is not greater than the table bound, return an absolute
|
||||
address corresponding to a byte offset of ``p`` from the table's
|
||||
base address.
|
||||
2. If ``p`` is greater than the table bound, generate a trap.
|
||||
""",
|
||||
ins=(T, p, Offset), outs=addr)
|
||||
|
||||
|
||||
#
|
||||
# Materializing constants.
|
||||
#
|
||||
|
||||
@@ -65,6 +65,7 @@ expand_flags = XFormGroup('expand_flags', """
|
||||
# Custom expansions for memory objects.
|
||||
expand.custom_legalize(insts.global_value, 'expand_global_value')
|
||||
expand.custom_legalize(insts.heap_addr, 'expand_heap_addr')
|
||||
expand.custom_legalize(insts.table_addr, 'expand_table_addr')
|
||||
|
||||
# Custom expansions for calls.
|
||||
expand.custom_legalize(insts.call, 'expand_call')
|
||||
|
||||
Reference in New Issue
Block a user