Packages
orb
0.0.48
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/memory/load.ex
defmodule Orb.Memory.Load do
@moduledoc false
defstruct push_type: nil, load_instruction: :load, address: nil, align: nil
require Orb.Ops |> alias
def new(type, address, opts) when is_atom(type) do
load_instruction =
cond do
Ops.is_primitive_type(type) ->
:load
type |> Code.ensure_loaded!() |> function_exported?(:load_instruction, 0) ->
type.load_instruction()
true ->
:load
end
align = Keyword.get(opts, :align)
primitive_type = Ops.to_primitive_type(type)
{_, natural_alignment} = store_and_alignment_for(primitive_type, load_instruction)
validate_align!(align, natural_alignment)
%__MODULE__{
push_type: type,
load_instruction: load_instruction,
address: address,
align: align
}
end
def new(primitive_type, load_instruction, address, opts)
when Ops.is_primitive_type(primitive_type) do
align = Keyword.get(opts, :align)
{_, natural_alignment} = store_and_alignment_for(primitive_type, load_instruction)
validate_align!(align, natural_alignment)
%__MODULE__{
push_type: primitive_type,
load_instruction: load_instruction,
address: address,
align: align
}
end
def store_and_alignment_for(primitive_type, load_instruction) do
case load_instruction do
i when i in [:load8_s, :load8_u] ->
{:store8, 1}
i when i in [:load16_s, :load16_u] ->
{:store16, 2}
i when i in [:load32_s, :load32_u] ->
{:store32, 4}
:load ->
case primitive_type do
t when t in [:i32, :f32] -> {:store, 4}
t when t in [:i64, :f64] -> {:store, 8}
end
end
end
def validate_align!(align, natural_alignment)
def validate_align!(nil, _), do: nil
def validate_align!(align, _) when align not in [1, 2, 4, 8] do
raise ArgumentError, "malformed alignment #{align}"
end
def validate_align!(align, natural_alignment) do
if align > natural_alignment do
raise ArgumentError,
"alignment #{align} must not be larger than natural #{natural_alignment}"
end
end
defimpl Orb.ToWat do
def to_wat(
%Orb.Memory.Load{
push_type: type,
load_instruction: load_instruction,
address: address,
align: align
},
indent
) do
[
indent,
"(",
Orb.ToWat.Helpers.do_type(type),
".",
to_string(load_instruction),
case align do
nil -> []
align -> [" align=", to_string(align)]
end,
[" ", Orb.ToWat.Instructions.do_wat(address)],
")"
]
end
end
end