Packages

An experimental work-in-progress (WIP) WebAssembly runtime written in Gleam.

Current section

Files

Jump to
gwr src section.erl
Raw

src/section.erl

-module(section).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([parse_raw_section/2, decode_custom_section/1, decode_memory_section/1, decode_section/2, from_raw_data/2]).
-export_type([raw_section/0, section/0]).
-type raw_section() :: {raw_section,
integer(),
integer(),
gleam@option:option(bitstring())}.
-type section() :: {custom,
integer(),
binary(),
gleam@option:option(bitstring())} |
{type, integer()} |
{import, integer()} |
{function, integer()} |
{table, integer()} |
{memory, integer(), list(types@limits:limits())} |
{global, integer()} |
{export, integer()} |
{start, integer()} |
{element, integer()} |
{code, integer()} |
{data, integer()} |
{data_count, integer()}.
-spec parse_raw_section(integer(), bitstring()) -> {ok, raw_section()} |
{error, binary()}.
parse_raw_section(Position, Raw_data) ->
gleam@result:'try'(
case gleam_stdlib:bit_array_slice(Raw_data, Position, 1) of
{ok, Section_type_id_raw_data} ->
case Section_type_id_raw_data of
<<Section_type_id_decoded>> ->
{ok, Section_type_id_decoded};
_ ->
{error,
<<"section::parse_raw_section: can't decode section type id raw data into an integer"/utf8>>}
end;
{error, _} ->
{error,
<<"section::parse_raw_section: can't get section type id raw data"/utf8>>}
end,
fun(Section_type_id) ->
gleam@result:'try'(
util:decode_u32leb128(Position + 1, Raw_data),
fun(_use0) ->
{Section_length, Section_length_word_size} = _use0,
Section_raw_content = case Section_length > 0 of
true ->
gleam@bool:guard(
(((Position + 1) + Section_length_word_size) + Section_length)
> erlang:byte_size(Raw_data),
{error,
<<"section::parse_raw_section: unexpected end of the section's content segment"/utf8>>},
fun() ->
case gleam_stdlib:bit_array_slice(
Raw_data,
(Position + 1) + Section_length_word_size,
Section_length
) of
{ok, Content} ->
{ok, {some, Content}};
{error, _} ->
{error,
<<"section::parse_raw_section: can't get the section's content segment"/utf8>>}
end
end
);
false ->
{ok, none}
end,
gleam@result:'try'(case Section_raw_content of
{ok, V} ->
{ok, V};
{error, Reason} ->
{error, Reason}
end, fun(Section_raw_content@1) ->
{ok,
{raw_section,
Section_type_id,
Section_length,
Section_raw_content@1}}
end)
end
)
end
).
-spec decode_custom_section(raw_section()) -> {ok, section()} |
{error, binary()}.
decode_custom_section(Raw_section) ->
case erlang:element(4, Raw_section) of
{some, Content} ->
gleam@result:'try'(
types@name:from_raw_data(0, Content),
fun(Custom_section_name) ->
gleam@result:'try'(
types@name:to_string(Custom_section_name),
fun(Name_string) ->
Name_length = types@name:length(Custom_section_name),
Content_length = erlang:byte_size(Content),
case gleam_stdlib:bit_array_slice(
Content,
Name_length + 1,
(Content_length - Name_length) - 1
) of
{ok, Custom_data} ->
{ok,
{custom,
erlang:element(3, Raw_section),
Name_string,
{some, Custom_data}}};
{error, _} ->
{error,
<<"section::decode_custom_section: can't get custom data"/utf8>>}
end
end
)
end
);
none ->
{error,
<<"section::decode_custom_section: empty section content"/utf8>>}
end.
-spec decode_memory_section(raw_section()) -> {ok, section()} |
{error, binary()}.
decode_memory_section(Raw_section) ->
case erlang:element(4, Raw_section) of
{some, Content} ->
gleam@result:'try'(
types@vector:from_raw_data(0, Content),
fun(Raw_vec) ->
gleam@result:'try'(
types@limits:from_vector(Raw_vec),
fun(Mem_vec) ->
{ok,
{memory,
erlang:element(3, Raw_section),
erlang:element(1, Mem_vec)}}
end
)
end
);
none ->
{error,
<<"section::decode_memory_section: empty section content"/utf8>>}
end.
-spec decode_section(integer(), bitstring()) -> {ok, section()} |
{error, binary()}.
decode_section(Position, Raw_data) ->
gleam@result:'try'(
parse_raw_section(Position, Raw_data),
fun(Parsed_raw_section) -> case erlang:element(2, Parsed_raw_section) of
N when N =:= 16#00 ->
decode_custom_section(Parsed_raw_section);
N@1 when N@1 =:= 16#05 ->
decode_memory_section(Parsed_raw_section);
_ ->
{error,
<<<<"section::decode_section: unknown section type id \""/utf8,
(gleam@int:to_string(
erlang:element(2, Parsed_raw_section)
))/binary>>/binary,
"\""/utf8>>}
end end
).
-spec from_raw_data(integer(), bitstring()) -> {ok, section()} |
{error, binary()}.
from_raw_data(Position, Raw_data) ->
gleam@result:'try'(
decode_section(Position, Raw_data),
fun(Sec) -> {ok, Sec} end
).