Define a "table" concept.

"Table" is to WebAssembly tables as "Heap" is to WebAssembly linear
memories.
This commit is contained in:
Dan Gohman
2018-05-20 07:48:46 -07:00
parent cd75176f10
commit 1b30265c5c
23 changed files with 500 additions and 16 deletions

View File

@@ -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.')

View File

@@ -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(

View File

@@ -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.
#

View File

@@ -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')