Packages
orb
0.2.0
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
0.0.51
0.0.49
0.0.48
0.0.47
0.0.46
0.0.45
0.0.44
0.0.43
0.0.42
0.0.41
0.0.40
0.0.39
0.0.38
0.0.37
0.0.36
0.0.35
0.0.34
0.0.33
0.0.32
0.0.31
0.0.30
0.0.28
0.0.27
0.0.26
0.0.25
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
retired
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
DSL for WebAssembly
Current section
Files
Jump to
Current section
Files
lib/orb/table.ex
defmodule Orb.Table do
defmodule Type do
@callback table_func_keys() :: list(atom())
end
defmacro allocate(entries) do
quote do
@wasm_table_allocations unquote(__MODULE__).__do_allocate(unquote(entries))
end
end
def __do_allocate(mod) when is_atom(mod) do
type_name = mod.type_name()
for key <- mod.table_func_keys() do
{{mod, key}, type_name}
end
|> __do_allocate()
# __do_allocate(mod.table_entries())
end
def __do_allocate(list) when is_list(list) do
list
end
defmodule Allocations do
@moduledoc false
defstruct lookup_table: []
def from_attribute(accumulated_value) do
lookup_table =
accumulated_value
|> Enum.reverse()
|> List.flatten()
|> Enum.with_index(fn {key, type}, index ->
{key, {index, type}}
end)
|> Map.new()
%__MODULE__{lookup_table: lookup_table}
end
def fetch!(%__MODULE__{lookup_table: lookup_table}, key) do
case Map.fetch(lookup_table, key) do
:error ->
{table_module, table_key} = key
raise "Could not find elem key #{inspect(table_key)} from table module #{table_module} in table allocations #{inspect(lookup_table)}"
{:ok, result} ->
result
end
end
def fetch_index!(%__MODULE__{} = self, key) do
{elem_index, _type} = fetch!(self, key)
elem_index
end
end
# def elem(f = %Orb.Func{}) when is_atom(f.name) do
# update_in(f.table_elem_refs, fn refs -> [f.name | refs] end)
# end
def do_elem(caller_mod, f, mod, key) do
# if Process.put(Orb.DSL, false) do
if function_exported?(caller_mod, :__wasm_table_allocations__, 0) do
Orb.Func.__add_table_elem(
f,
Allocations.fetch_index!(caller_mod.__wasm_table_allocations__(), {mod, key})
)
else
f
end
end
defmacro elem!(f, mod, key) do
caller_mod = __CALLER__.module
quote do
unquote(__MODULE__).do_elem(unquote(caller_mod), unquote(f), unquote(mod), unquote(key))
# Orb.Func.__add_table_elem(unquote(f), Allocations.fetch_index!(unquote(caller_mod).__wasm_table_allocations__(), {unquote(mod), unquote(key)}))
end
end
defmacro fetch!(key) do
quote do
Allocations.fetch!(__wasm_table_allocations__(), unquote(key))
end
end
defmacro lookup!(key) do
caller_mod = __CALLER__.module
quote do
Allocations.fetch_index!(unquote(caller_mod).__wasm_table_allocations__(), unquote(key))
end
end
defmacro lookup!(table_mod, key) do
caller_mod = __CALLER__.module
quote do
Allocations.fetch_index!(
unquote(caller_mod).__wasm_table_allocations__(),
{unquote(table_mod), unquote(key)}
)
end
end
# def elem(f = %Orb.Func{}, elem_ref) when is_function(elem_ref) do
# update_in(f.table_elem_refs, fn refs -> [elem_ref | refs] end)
# end
defmodule CallIndirect do
@moduledoc false
defstruct pop_type: nil,
push_type: nil,
type_signature: nil,
table_index: 0,
arguments: []
defimpl Orb.ToWat do
def to_wat(
%Orb.Table.CallIndirect{
type_signature: type_signature,
table_index: table_index,
arguments: arguments
},
indent
) do
[
indent,
"(call_indirect (type $",
to_string(type_signature),
")",
for(arg <- arguments, do: [" ", Orb.ToWat.to_wat(arg, "")]),
" (i32.const ",
to_string(table_index),
?),
?)
]
end
end
end
def call({table_index, type_signature}) do
%CallIndirect{type_signature: type_signature, table_index: table_index}
end
def call({table_index, type_signature}, arg1) do
%CallIndirect{type_signature: type_signature, table_index: table_index, arguments: [arg1]}
end
def call({table_index, type_signature}, arg1, arg2) do
%CallIndirect{
type_signature: type_signature,
table_index: table_index,
arguments: [arg1, arg2]
}
end
def call({table_index, type_signature}, arg1, arg2, arg3) do
%CallIndirect{
type_signature: type_signature,
table_index: table_index,
arguments: [arg1, arg2, arg3]
}
end
def call({table_index, type_signature}, arg1, arg2, arg3, arg4) do
%CallIndirect{
type_signature: type_signature,
table_index: table_index,
arguments: [arg1, arg2, arg3, arg4]
}
end
def call_indirect(func_type, type_signature, table_index) do
do_call_indirect(func_type, type_signature, table_index, [])
end
def call_indirect(func_type, type_signature, table_index, arg1) do
do_call_indirect(func_type, type_signature, table_index, [arg1])
end
def call_indirect(func_type, type_signature, table_index, arg1, arg2) do
do_call_indirect(func_type, type_signature, table_index, [arg1, arg2])
end
def call_indirect(func_type, type_signature, table_index, arg1, arg2, arg3) do
do_call_indirect(func_type, type_signature, table_index, [arg1, arg2, arg3])
end
def call_indirect(func_type, type_signature, table_index, arg1, arg2, arg3, arg4) do
do_call_indirect(func_type, type_signature, table_index, [arg1, arg2, arg3, arg4])
end
defp do_call_indirect(func_type = %Orb.Func.Type{}, type_signature, table_index, arguments) do
%CallIndirect{
pop_type: func_type.params,
# pop_type: if(func_type.params, do: for(param <- func_type.params, do: param.type)),
push_type: func_type.result,
type_signature: type_signature,
table_index: table_index,
arguments: arguments
}
end
end