Packages

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

Current section

Files

Jump to
gwr src gwr@exec.erl
Raw

src/gwr@exec.erl

-module(gwr@exec).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gwr/exec.gleam").
-export([update_references/2, append_web_assembly_function/3, append_memory/2, ieee_float_to_builtin_float/1, builtin_float_to_ieee_float/1, address_to_int/1, initialize/1, address_to_string/1, evaluate_const/3, evaluate_iadd/2, evaluate_isub/2, evaluate_imul/2, evaluate_idiv_u/2, evaluate_idiv_s/2, evaluate_irem_u/2, evaluate_irem_s/2, evaluate_iand/2, evaluate_ior/2, evaluate_ixor/2, evaluate_ishl/2, evaluate_ishr_u/2, evaluate_ishr_s/2, evaluate_irotl/2, evaluate_irotr/2, evaluate_iclz/2, evaluate_ictz/2, evaluate_ipopcnt/2, evaluate_ieqz/2, evaluate_ieq/2, evaluate_ine/2, evaluate_ilt_u/2, evaluate_ilt_s/2, evaluate_igt_u/2, evaluate_igt_s/2, evaluate_ile_u/2, evaluate_ile_s/2, evaluate_ige_u/2, evaluate_ige_s/2, evaluate_iextend8_s/2, evaluate_iextend16_s/2, evaluate_iextend32_s/2, evaluate_local_get/2, evaluate_local_set/2, evaluate_local_tee/2, evaluate_return/1, evaluate_br/3, evaluate_br_if/3, exit_with_label/2, unwind_stack/1, expand_block_type/2, evaluate_call/3, evaluate_invoke/3, evaluate_with_frame/4, enter_with_label/5, evaluate_expression/3, invoke/3, evaluate_loop/4, evaluate_block/4, evaluate_if_else/5]).
-export_type([state/0, const_value/0, unary_operation_type/0, binary_operation_type/0, test_operation_type/0, comparison_operation_type/0, jump/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type state() :: {state,
gwr@spec:module_instance(),
gwr@exec@stack:stack(),
gwr@spec:store()}.
-type const_value() :: {integer_const_value, integer()} |
{float_const_value, ieee_float:i_e_e_e_float()}.
-type unary_operation_type() :: {integer_unary_operation,
fun((gwr@spec:number_type(), integer()) -> {ok, integer()} |
{error, gwr@exec@trap:trap()})} |
{float_unary_operation,
fun((ieee_float:i_e_e_e_float()) -> {ok, gwr@spec:value()} |
{error, gwr@exec@trap:trap()})}.
-type binary_operation_type() :: {integer_binary_operation,
fun((gwr@spec:number_type(), integer(), integer()) -> {ok, integer()} |
{error, gwr@exec@trap:trap()})} |
{float_binary_operation,
fun((ieee_float:i_e_e_e_float(), ieee_float:i_e_e_e_float()) -> {ok,
gwr@spec:value()} |
{error, gwr@exec@trap:trap()})}.
-type test_operation_type() :: {integer_test_operation,
fun((integer()) -> {ok, integer()} | {error, gwr@exec@trap:trap()})} |
{float_test_operation,
fun((ieee_float:i_e_e_e_float()) -> {ok, integer()} |
{error, gwr@exec@trap:trap()})}.
-type comparison_operation_type() :: {integer_comparison_operation,
fun((gwr@spec:number_type(), integer(), integer()) -> {ok, integer()} |
{error, gwr@exec@trap:trap()})} |
{float_comparison_operation,
fun((ieee_float:i_e_e_e_float(), ieee_float:i_e_e_e_float()) -> {ok,
integer()} |
{error, gwr@exec@trap:trap()})}.
-type jump() :: {branch, list(gwr@spec:instruction())} | return.
-file("src/gwr/exec.gleam", 86).
-spec update_references(gwr@spec:store(), gwr@spec:module_instance()) -> gwr@spec:store().
update_references(Store, New_module_instance) ->
Updated_functions = gleam@dict:map_values(
erlang:element(2, Store),
fun(_, Function) -> case Function of
{web_assembly_function_instance, Type_, _, Code} ->
{web_assembly_function_instance,
Type_,
New_module_instance,
Code};
_ ->
Function
end end
),
{store,
Updated_functions,
erlang:element(3, Store),
erlang:element(4, Store),
erlang:element(5, Store),
erlang:element(6, Store),
erlang:element(7, Store)}.
-file("src/gwr/exec.gleam", 134).
-spec append_web_assembly_function(
gwr@spec:store(),
gwr@spec:function_(),
list(gwr@spec:function_type())
) -> {ok, gwr@spec:store()} | {error, binary()}.
append_web_assembly_function(Store, Function, Types_list) ->
Empty_module_instance = {module_instance,
[],
maps:new(),
[],
[],
[],
[],
[],
[]},
Function_address = {function_address,
begin
_pipe = maps:keys(erlang:element(2, Store)),
erlang:length(_pipe)
end},
case begin
_pipe@1 = Types_list,
_pipe@2 = gleam@list:take(_pipe@1, erlang:element(2, Function) + 1),
gleam@list:last(_pipe@2)
end of
{ok, Function_type} ->
{ok,
{store,
gleam@dict:insert(
erlang:element(2, Store),
Function_address,
{web_assembly_function_instance,
Function_type,
Empty_module_instance,
Function}
),
erlang:element(3, Store),
erlang:element(4, Store),
erlang:element(5, Store),
erlang:element(6, Store),
erlang:element(7, Store)}};
{error, _} ->
{error,
<<"couldn't find the type of the function among types list"/utf8>>}
end.
-file("src/gwr/exec.gleam", 174).
-spec append_memory(gwr@spec:store(), gwr@spec:memory()) -> gwr@spec:store().
append_memory(Store, Memory) ->
Memory_data = <<16#00:(lists:max([((erlang:element(
2,
erlang:element(2, Memory)
)
* 65536)), 0]))>>,
{store,
erlang:element(2, Store),
erlang:element(3, Store),
lists:append(
erlang:element(4, Store),
[{memory_instance, erlang:element(2, Memory), Memory_data}]
),
erlang:element(5, Store),
erlang:element(6, Store),
erlang:element(7, Store)}.
-file("src/gwr/exec.gleam", 187).
-spec ieee_float_to_builtin_float(ieee_float:i_e_e_e_float()) -> {ok,
gwr@spec:float_value()} |
{error, gwr@exec@trap:trap()}.
ieee_float_to_builtin_float(Value) ->
case ieee_float:is_finite(Value) of
true ->
gleam@result:'try'(
gleam@result:replace_error(
ieee_float:to_finite(Value),
begin
_pipe = gwr@exec@trap:make(unknown),
gwr@exec@trap:add_message(
_pipe,
<<"ieee_float.to_finite error"/utf8>>
)
end
),
fun(Fin) -> {ok, {finite, Fin}} end
);
false ->
case ieee_float:is_nan(Value) of
true ->
{ok, na_n};
false ->
case ieee_float:compare(
Value,
ieee_float:positive_infinity()
) of
{ok, eq} ->
{ok, {infinite, positive}};
{ok, lt} ->
{ok, {infinite, negative}};
_ ->
_pipe@1 = gwr@exec@trap:make(unknown),
_pipe@2 = gwr@exec@trap:add_message(
_pipe@1,
<<"ieee_float.compare error"/utf8>>
),
gwr@exec@trap:to_error(_pipe@2)
end
end
end.
-file("src/gwr/exec.gleam", 215).
-spec builtin_float_to_ieee_float(gwr@spec:float_value()) -> ieee_float:i_e_e_e_float().
builtin_float_to_ieee_float(Value) ->
case Value of
{finite, V} ->
ieee_float:finite(V);
{infinite, positive} ->
ieee_float:positive_infinity();
{infinite, negative} ->
ieee_float:negative_infinity();
na_n ->
ieee_float:nan()
end.
-file("src/gwr/exec.gleam", 226).
-spec address_to_int(gwr@spec:address()) -> integer().
address_to_int(Address) ->
case Address of
{function_address, Addr} ->
Addr;
{table_address, Addr@1} ->
Addr@1;
{memory_address, Addr@2} ->
Addr@2;
{global_address, Addr@3} ->
Addr@3;
{element_address, Addr@4} ->
Addr@4;
{data_address, Addr@5} ->
Addr@5;
{extern_address, Addr@6} ->
Addr@6
end.
-file("src/gwr/exec.gleam", 26).
-spec initialize(gwr@spec:module_()) -> {ok, state()} | {error, binary()}.
initialize(Module) ->
Store = {store, maps:new(), [], [], [], [], []},
gleam@result:'try'(
gleam@list:fold(
erlang:element(3, Module),
{ok, Store},
fun(Store@1, Function) ->
gleam@result:'try'(
Store@1,
fun(Store@2) ->
gleam@result:'try'(
begin
_pipe = Store@2,
append_web_assembly_function(
_pipe,
Function,
erlang:element(2, Module)
)
end,
fun(Store@3) -> {ok, Store@3} end
)
end
)
end
),
fun(Store@4) ->
Store@6 = gleam@list:fold(
erlang:element(5, Module),
Store@4,
fun(Store@5, Memory) -> _pipe@1 = Store@5,
append_memory(_pipe@1, Memory) end
),
Module_instance = {module_instance,
erlang:element(2, Module),
begin
_pipe@2 = erlang:element(2, Store@6),
_pipe@3 = maps:to_list(_pipe@2),
_pipe@4 = gleam@list:map(
_pipe@3,
fun(X) ->
{address_to_int(erlang:element(1, X)),
erlang:element(1, X)}
end
),
maps:from_list(_pipe@4)
end,
[],
gleam@list:index_map(
erlang:element(4, Store@6),
fun(_, Index) -> {memory_address, Index} end
),
[],
[],
[],
[]},
{ok,
{state,
Module_instance,
gwr@exec@stack:create(),
update_references(Store@6, Module_instance)}}
end
).
-file("src/gwr/exec.gleam", 238).
-spec address_to_string(gwr@spec:address()) -> binary().
address_to_string(Address) ->
erlang:integer_to_binary(address_to_int(Address)).
-file("src/gwr/exec.gleam", 282).
?DOC(" https://webassembly.github.io/spec/core/exec/instructions.html#t-mathsf-xref-syntax-instructions-syntax-unop-mathit-unop\n").
-spec unary_operation(
gwr@exec@stack:stack(),
gwr@spec:number_type(),
unary_operation_type()
) -> {ok, gwr@exec@stack:stack()} | {error, gwr@exec@trap:trap()}.
unary_operation(Stack, Type_, Operation_type) ->
{Stack@1, Values} = gwr@exec@stack:pop(Stack),
gleam@result:'try'(case {Type_, Operation_type, Values} of
{integer32,
{integer_unary_operation, Unop},
{some, {value_entry, {integer32_value, C1}}}} ->
gleam@result:'try'(Unop(Type_, C1), fun(C) -> case Type_ of
integer32 ->
{ok, {integer32_value, C}};
_ ->
{ok, {integer64_value, C}}
end end);
{integer64,
{integer_unary_operation, Unop},
{some, {value_entry, {integer64_value, C1}}}} ->
gleam@result:'try'(Unop(Type_, C1), fun(C) -> case Type_ of
integer32 ->
{ok, {integer32_value, C}};
_ ->
{ok, {integer64_value, C}}
end end);
{float32,
{float_unary_operation, Unop@1},
{some, {value_entry, {float32_value, C1@1}}}} ->
Unop@1(builtin_float_to_ieee_float(C1@1));
{float64,
{float_unary_operation, Unop@1},
{some, {value_entry, {float64_value, C1@1}}}} ->
Unop@1(builtin_float_to_ieee_float(C1@1));
{T, H, Args} ->
_pipe = gwr@exec@trap:make(bad_argument),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
gleam@string:inspect({T, H, Args})
),
gwr@exec@trap:to_error(_pipe@1)
end, fun(C@1) ->
{ok, gwr@exec@stack:push(Stack@1, [{value_entry, C@1}])}
end).
-file("src/gwr/exec.gleam", 328).
?DOC(" https://webassembly.github.io/spec/core/exec/instructions.html#t-mathsf-xref-syntax-instructions-syntax-binop-mathit-binop\n").
-spec binary_operation(
gwr@exec@stack:stack(),
gwr@spec:number_type(),
binary_operation_type()
) -> {ok, gwr@exec@stack:stack()} | {error, gwr@exec@trap:trap()}.
binary_operation(Stack, Type_, Operation_type) ->
{Stack@1, Values} = gwr@exec@stack:pop_repeat(Stack, 2),
gleam@result:'try'(case {Type_, Operation_type, Values} of
{integer32,
{integer_binary_operation, Binop},
[{value_entry, {integer32_value, C2}},
{value_entry, {integer32_value, C1}}]} ->
gleam@result:'try'(Binop(Type_, C1, C2), fun(C) -> case Type_ of
integer32 ->
{ok, {integer32_value, C}};
_ ->
{ok, {integer64_value, C}}
end end);
{integer64,
{integer_binary_operation, Binop},
[{value_entry, {integer64_value, C2}},
{value_entry, {integer64_value, C1}}]} ->
gleam@result:'try'(Binop(Type_, C1, C2), fun(C) -> case Type_ of
integer32 ->
{ok, {integer32_value, C}};
_ ->
{ok, {integer64_value, C}}
end end);
{float32,
{float_binary_operation, Binop@1},
[{value_entry, {float32_value, C2@1}},
{value_entry, {float32_value, C1@1}}]} ->
Binop@1(
builtin_float_to_ieee_float(C1@1),
builtin_float_to_ieee_float(C2@1)
);
{float64,
{float_binary_operation, Binop@1},
[{value_entry, {float64_value, C2@1}},
{value_entry, {float64_value, C1@1}}]} ->
Binop@1(
builtin_float_to_ieee_float(C1@1),
builtin_float_to_ieee_float(C2@1)
);
{T, H, Args} ->
_pipe = gwr@exec@trap:make(bad_argument),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
gleam@string:inspect({T, H, Args})
),
gwr@exec@trap:to_error(_pipe@1)
end, fun(C@1) ->
{ok, gwr@exec@stack:push(Stack@1, [{value_entry, C@1}])}
end).
-file("src/gwr/exec.gleam", 386).
-spec get_bitwidth(gwr@spec:number_type()) -> integer().
get_bitwidth(Type_) ->
case Type_ of
integer32 ->
32;
float32 ->
32;
integer64 ->
64;
float64 ->
64
end.
-file("src/gwr/exec.gleam", 394).
?DOC(" https://webassembly.github.io/spec/core/exec/instructions.html#t-mathsf-xref-syntax-instructions-syntax-testop-mathit-testop\n").
-spec test_operation(
gwr@exec@stack:stack(),
gwr@spec:number_type(),
test_operation_type()
) -> {ok, gwr@exec@stack:stack()} | {error, gwr@exec@trap:trap()}.
test_operation(Stack, Type_, Operation_type) ->
{Stack@1, Values} = gwr@exec@stack:pop(Stack),
gleam@result:'try'(case {Type_, Operation_type, Values} of
{integer32,
{integer_test_operation, Testop},
{some, {value_entry, {integer32_value, C1}}}} ->
Testop(C1);
{integer64,
{integer_test_operation, Testop},
{some, {value_entry, {integer64_value, C1}}}} ->
Testop(C1);
{float32,
{float_test_operation, Testop@1},
{some, {value_entry, {float32_value, C1@1}}}} ->
Testop@1(builtin_float_to_ieee_float(C1@1));
{float64,
{float_test_operation, Testop@1},
{some, {value_entry, {float64_value, C1@1}}}} ->
Testop@1(builtin_float_to_ieee_float(C1@1));
{T, H, Args} ->
_pipe = gwr@exec@trap:make(bad_argument),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
gleam@string:inspect({T, H, Args})
),
gwr@exec@trap:to_error(_pipe@1)
end, fun(C) ->
{ok,
gwr@exec@stack:push(
Stack@1,
[{value_entry, {integer32_value, C}}]
)}
end).
-file("src/gwr/exec.gleam", 432).
?DOC(" https://webassembly.github.io/spec/core/exec/instructions.html#t-mathsf-xref-syntax-instructions-syntax-relop-mathit-relop\n").
-spec comparison_operation(
gwr@exec@stack:stack(),
gwr@spec:number_type(),
comparison_operation_type()
) -> {ok, gwr@exec@stack:stack()} | {error, gwr@exec@trap:trap()}.
comparison_operation(Stack, Type_, Operation_type) ->
{Stack@1, Values} = gwr@exec@stack:pop_repeat(Stack, 2),
gleam@result:'try'(case {Type_, Operation_type, Values} of
{integer32,
{integer_comparison_operation, Relop},
[{value_entry, {integer32_value, C2}},
{value_entry, {integer32_value, C1}}]} ->
Relop(Type_, C1, C2);
{integer64,
{integer_comparison_operation, Relop},
[{value_entry, {integer64_value, C2}},
{value_entry, {integer64_value, C1}}]} ->
Relop(Type_, C1, C2);
{float32,
{float_comparison_operation, Relop@1},
[{value_entry, {float32_value, C2@1}},
{value_entry, {float32_value, C1@1}}]} ->
Relop@1(
builtin_float_to_ieee_float(C1@1),
builtin_float_to_ieee_float(C2@1)
);
{float64,
{float_comparison_operation, Relop@1},
[{value_entry, {float64_value, C2@1}},
{value_entry, {float64_value, C1@1}}]} ->
Relop@1(
builtin_float_to_ieee_float(C1@1),
builtin_float_to_ieee_float(C2@1)
);
{T, H, Args} ->
_pipe = gwr@exec@trap:make(bad_argument),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
gleam@string:inspect({T, H, Args})
),
gwr@exec@trap:to_error(_pipe@1)
end, fun(C) ->
{ok,
gwr@exec@stack:push(
Stack@1,
[{value_entry, {integer32_value, C}}]
)}
end).
-file("src/gwr/exec.gleam", 483).
?DOC(" https://webassembly.github.io/spec/core/exec/instructions.html#t-mathsf-xref-syntax-instructions-syntax-instr-numeric-mathsf-const-c\n").
-spec evaluate_const(
gwr@exec@stack:stack(),
gwr@spec:number_type(),
const_value()
) -> {ok, gwr@exec@stack:stack()} | {error, gwr@exec@trap:trap()}.
evaluate_const(Stack, Type_, Value) ->
gleam@result:'try'(case {Type_, Value} of
{integer32, {integer_const_value, Value@1}} ->
{ok, {integer32_value, Value@1}};
{integer64, {integer_const_value, Value@2}} ->
{ok, {integer64_value, Value@2}};
{float32, {float_const_value, Value@3}} ->
gleam@result:'try'(
ieee_float_to_builtin_float(Value@3),
fun(Built_in_float) ->
{ok, {float32_value, Built_in_float}}
end
);
{float64, {float_const_value, Value@4}} ->
gleam@result:'try'(
ieee_float_to_builtin_float(Value@4),
fun(Built_in_float@1) ->
{ok, {float64_value, Built_in_float@1}}
end
);
{_, _} ->
_pipe = gwr@exec@trap:make(bad_argument),
gwr@exec@trap:to_error(_pipe)
end, fun(C) -> {ok, gwr@exec@stack:push(Stack, [{value_entry, C}])} end).
-file("src/gwr/exec.gleam", 507).
-spec evaluate_iadd(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_iadd(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> {ok, gwr@exec@arith:iadd(get_bitwidth(T), A, B)} end}
).
-file("src/gwr/exec.gleam", 518).
-spec evaluate_isub(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_isub(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> {ok, gwr@exec@arith:isub(get_bitwidth(T), A, B)} end}
).
-file("src/gwr/exec.gleam", 529).
-spec evaluate_imul(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_imul(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> {ok, gwr@exec@arith:imul(get_bitwidth(T), A, B)} end}
).
-file("src/gwr/exec.gleam", 540).
-spec evaluate_idiv_u(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_idiv_u(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:idiv_u(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 551).
-spec evaluate_idiv_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_idiv_s(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:idiv_s(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 562).
-spec evaluate_irem_u(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_irem_u(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:irem_u(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 573).
-spec evaluate_irem_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_irem_s(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:irem_s(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 584).
-spec evaluate_iand(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_iand(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> {ok, gwr@exec@arith:iand(get_bitwidth(T), A, B)} end}
).
-file("src/gwr/exec.gleam", 595).
-spec evaluate_ior(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ior(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> {ok, gwr@exec@arith:ior(get_bitwidth(T), A, B)} end}
).
-file("src/gwr/exec.gleam", 606).
-spec evaluate_ixor(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ixor(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> {ok, gwr@exec@arith:ixor(get_bitwidth(T), A, B)} end}
).
-file("src/gwr/exec.gleam", 617).
-spec evaluate_ishl(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ishl(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:ishl(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 628).
-spec evaluate_ishr_u(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ishr_u(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:ishr_u(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 639).
-spec evaluate_ishr_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ishr_s(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:ishr_s(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 650).
-spec evaluate_irotl(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_irotl(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:irotl(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 661).
-spec evaluate_irotr(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_irotr(Stack, Type_) ->
binary_operation(
Stack,
Type_,
{integer_binary_operation,
fun(T, A, B) -> gwr@exec@arith:irotr(get_bitwidth(T), A, B) end}
).
-file("src/gwr/exec.gleam", 672).
-spec evaluate_iclz(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_iclz(Stack, Type_) ->
unary_operation(
Stack,
Type_,
{integer_unary_operation,
fun(T, A) -> gwr@exec@arith:iclz(get_bitwidth(T), A) end}
).
-file("src/gwr/exec.gleam", 683).
-spec evaluate_ictz(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ictz(Stack, Type_) ->
unary_operation(
Stack,
Type_,
{integer_unary_operation,
fun(T, A) -> gwr@exec@arith:ictz(get_bitwidth(T), A) end}
).
-file("src/gwr/exec.gleam", 694).
-spec evaluate_ipopcnt(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ipopcnt(Stack, Type_) ->
unary_operation(
Stack,
Type_,
{integer_unary_operation,
fun(T, A) -> gwr@exec@arith:ipopcnt(get_bitwidth(T), A) end}
).
-file("src/gwr/exec.gleam", 705).
-spec evaluate_ieqz(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ieqz(Stack, Type_) ->
test_operation(
Stack,
Type_,
{integer_test_operation, fun(A) -> {ok, gwr@exec@arith:ieqz(A)} end}
).
-file("src/gwr/exec.gleam", 716).
-spec evaluate_ieq(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ieq(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(_, A, B) -> {ok, gwr@exec@arith:ieq(A, B)} end}
).
-file("src/gwr/exec.gleam", 727).
-spec evaluate_ine(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ine(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(_, A, B) -> {ok, gwr@exec@arith:ine(A, B)} end}
).
-file("src/gwr/exec.gleam", 738).
-spec evaluate_ilt_u(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ilt_u(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:ilt_u(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 751).
-spec evaluate_ilt_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ilt_s(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:ilt_s(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 764).
-spec evaluate_igt_u(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_igt_u(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:igt_u(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 777).
-spec evaluate_igt_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_igt_s(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:igt_s(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 790).
-spec evaluate_ile_u(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ile_u(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:ile_u(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 803).
-spec evaluate_ile_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ile_s(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:ile_s(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 816).
-spec evaluate_ige_u(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ige_u(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:ige_u(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 829).
-spec evaluate_ige_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_ige_s(Stack, Type_) ->
comparison_operation(
Stack,
Type_,
{integer_comparison_operation,
fun(T, A, B) ->
{ok, gwr@exec@arith:ige_s(get_bitwidth(T), A, B)}
end}
).
-file("src/gwr/exec.gleam", 842).
-spec evaluate_iextend8_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_iextend8_s(Stack, Type_) ->
unary_operation(
Stack,
Type_,
{integer_unary_operation,
fun(T, A) -> gwr@exec@arith:iextend8_s(get_bitwidth(T), A) end}
).
-file("src/gwr/exec.gleam", 853).
-spec evaluate_iextend16_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_iextend16_s(Stack, Type_) ->
unary_operation(
Stack,
Type_,
{integer_unary_operation,
fun(T, A) -> gwr@exec@arith:iextend16_s(get_bitwidth(T), A) end}
).
-file("src/gwr/exec.gleam", 864).
-spec evaluate_iextend32_s(gwr@exec@stack:stack(), gwr@spec:number_type()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_iextend32_s(Stack, Type_) ->
unary_operation(
Stack,
Type_,
{integer_unary_operation,
fun(T, A) -> gwr@exec@arith:iextend32_s(get_bitwidth(T), A) end}
).
-file("src/gwr/exec.gleam", 875).
-spec evaluate_local_get(gwr@exec@stack:stack(), integer()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_local_get(Stack, Index) ->
gleam@result:'try'(
gleam@result:replace_error(
gwr@exec@stack:get_current_frame(Stack),
begin
_pipe = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe,
<<"couldn't get the current frame"/utf8>>
)
end
),
fun(Frame) ->
gleam@result:'try'(
gleam@result:replace_error(
gleam_stdlib:map_get(
erlang:element(2, erlang:element(3, Frame)),
Index
),
begin
_pipe@1 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the local with index "/utf8,
(erlang:integer_to_binary(Index))/binary>>
)
end
),
fun(Local) ->
{ok, gwr@exec@stack:push(Stack, [{value_entry, Local}])}
end
)
end
).
-file("src/gwr/exec.gleam", 898).
-spec evaluate_local_set(gwr@exec@stack:stack(), integer()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_local_set(Stack, Index) ->
gleam@result:'try'(
gleam@result:replace_error(
gwr@exec@stack:get_current_frame(Stack),
begin
_pipe = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe,
<<"couldn't get the current frame"/utf8>>
)
end
),
fun(Frame) ->
gleam@result:'try'(
gleam@result:replace_error(
gleam_stdlib:map_get(
erlang:element(2, erlang:element(3, Frame)),
Index
),
begin
_pipe@1 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the local with index "/utf8,
(erlang:integer_to_binary(Index))/binary>>
)
end
),
fun(_) ->
gleam@result:'try'(
begin
_pipe@2 = gwr@exec@stack:pop_as(
Stack,
fun gwr@exec@stack:to_value/1
),
gleam@result:replace_error(
_pipe@2,
begin
_pipe@3 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@3,
<<"couldn't pop the value from stack"/utf8>>
)
end
)
end,
fun(_use0) ->
{Stack@1, Value} = _use0,
gleam@result:'try'(
begin
_pipe@4 = gwr@exec@stack:replace_current_frame(
Stack@1,
{frame,
erlang:element(2, Frame),
begin
_record = erlang:element(
3,
Frame
),
{frame_state,
gleam@dict:insert(
erlang:element(
2,
erlang:element(
3,
Frame
)
),
Index,
Value
),
erlang:element(3, _record)}
end}
),
gleam@result:replace_error(
_pipe@4,
begin
_pipe@5 = gwr@exec@trap:make(
invalid_state
),
gwr@exec@trap:add_message(
_pipe@5,
<<"couldn't update the current frame"/utf8>>
)
end
)
end,
fun(Stack@2) -> {ok, Stack@2} end
)
end
)
end
)
end
).
-file("src/gwr/exec.gleam", 951).
-spec evaluate_local_tee(gwr@exec@stack:stack(), integer()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
evaluate_local_tee(Stack, Index) ->
case gwr@exec@stack:pop(Stack) of
{Stack@1, {some, {value_entry, Val}}} ->
Stack@2 = gwr@exec@stack:push(
Stack@1,
[{value_entry, Val}, {value_entry, Val}]
),
evaluate_local_set(Stack@2, Index);
_ ->
_pipe = gwr@exec@trap:make(invalid_state),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
<<"expected a value on the top of the stack"/utf8>>
),
gwr@exec@trap:to_error(_pipe@1)
end.
-file("src/gwr/exec.gleam", 976).
-spec get_default_value_for_type(gwr@spec:value_type()) -> gwr@spec:value().
get_default_value_for_type(Type_) ->
case Type_ of
{number, integer32} ->
{integer32_value, 0};
{number, integer64} ->
{integer64_value, 0};
{number, float32} ->
{float32_value, {finite, erlang:float(0)}};
{number, float64} ->
{float64_value, {finite, erlang:float(0)}};
{vector, vector128} ->
{vector_value, 0};
{reference, function_reference} ->
{reference_value, null_reference};
{reference, extern_reference} ->
{reference_value, null_reference}
end.
-file("src/gwr/exec.gleam", 999).
-spec evaluate_return(gwr@exec@stack:stack()) -> {ok,
{gwr@exec@stack:stack(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
evaluate_return(Stack) ->
gleam@result:'try'(
begin
_pipe = gwr@exec@stack:get_current_frame(Stack),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the current frame"/utf8>>
)
end
)
end,
fun(Frame) ->
N = erlang:element(2, Frame),
Count_of_values_on_top = gwr@exec@stack:count_on_top(
Stack,
fun gwr@exec@stack:is_value/1
),
gleam@bool:guard(
Count_of_values_on_top < N,
begin
_pipe@2 = gwr@exec@trap:make(invalid_state),
_pipe@3 = gwr@exec@trap:add_message(
_pipe@2,
<<<<<<"expected the top of the stack to contains at least "/utf8,
(erlang:integer_to_binary(N))/binary>>/binary,
" values but got "/utf8>>/binary,
(erlang:integer_to_binary(Count_of_values_on_top))/binary>>
),
gwr@exec@trap:to_error(_pipe@3)
end,
fun() ->
{Stack@1, Results} = gwr@exec@stack:pop_repeat(Stack, N),
gleam@bool:guard(
begin
_pipe@4 = gwr@exec@stack:get_entries(Stack@1),
_pipe@5 = gleam@list:filter(
_pipe@4,
fun gwr@exec@stack:is_activation_frame/1
),
erlang:length(_pipe@5)
end
=< 0,
begin
_pipe@6 = gwr@exec@trap:make(invalid_state),
_pipe@7 = gwr@exec@trap:add_message(
_pipe@6,
<<"expected the stack to contains at least one frame"/utf8>>
),
gwr@exec@trap:to_error(_pipe@7)
end,
fun() ->
{Stack@2, _} = gwr@exec@stack:pop_while(
Stack@1,
fun(Entry) ->
not gwr@exec@stack:is_activation_frame(
Entry
)
end
),
gleam@bool:guard(
gwr@exec@stack:peek(Stack@2) /= {some,
{activation_entry, Frame}},
begin
_pipe@8 = gwr@exec@trap:make(invalid_state),
_pipe@9 = gwr@exec@trap:add_message(
_pipe@8,
<<"expected the top of the stack to be the current frame"/utf8>>
),
gwr@exec@trap:to_error(_pipe@9)
end,
fun() ->
{Stack@3, _} = gwr@exec@stack:pop(Stack@2),
Stack@4 = gwr@exec@stack:push(
Stack@3,
begin
_pipe@10 = Results,
lists:reverse(_pipe@10)
end
),
{ok, {Stack@4, {some, return}}}
end
)
end
)
end
)
end
).
-file("src/gwr/exec.gleam", 1241).
-spec evaluate_br(gwr@exec@stack:stack(), gwr@spec:store(), integer()) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
evaluate_br(Stack, Store, Index) ->
All_labels = begin
_pipe = erlang:element(2, gwr@exec@stack:pop_all(Stack)),
gleam@list:filter(_pipe, fun gwr@exec@stack:is_label/1)
end,
Count_of_labels_in_stack = begin
_pipe@1 = All_labels,
erlang:length(_pipe@1)
end,
gleam@bool:guard(
Count_of_labels_in_stack < (Index + 1),
begin
_pipe@2 = gwr@exec@trap:make(invalid_state),
_pipe@3 = gwr@exec@trap:add_message(
_pipe@2,
<<<<<<"expected the stack to contains at least "/utf8,
(erlang:integer_to_binary(Index + 1))/binary>>/binary,
" labels but got "/utf8>>/binary,
(erlang:integer_to_binary(Count_of_labels_in_stack))/binary>>
),
gwr@exec@trap:to_error(_pipe@3)
end,
fun() ->
gleam@result:'try'(
begin
_pipe@4 = All_labels,
_pipe@5 = gleam@list:take(_pipe@4, Index + 1),
_pipe@6 = gleam@list:last(_pipe@5),
gleam@result:replace_error(
_pipe@6,
begin
_pipe@7 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@7,
<<"couldn't find the label with index "/utf8,
(erlang:integer_to_binary(Index))/binary>>
)
end
)
end,
fun(Label_entry) ->
gleam@result:'try'(
gwr@exec@stack:to_label(Label_entry),
fun(Label) ->
N = erlang:element(2, Label),
Count_of_values_on_top = gwr@exec@stack:count_on_top(
Stack,
fun gwr@exec@stack:is_value/1
),
gleam@bool:guard(
Count_of_values_on_top < N,
begin
_pipe@8 = gwr@exec@trap:make(invalid_state),
_pipe@9 = gwr@exec@trap:add_message(
_pipe@8,
<<<<<<"expected the top of the stack to contains at least "/utf8,
(erlang:integer_to_binary(N))/binary>>/binary,
" values but got "/utf8>>/binary,
(erlang:integer_to_binary(
Count_of_values_on_top
))/binary>>
),
gwr@exec@trap:to_error(_pipe@9)
end,
fun() ->
{Stack@1, Values} = gwr@exec@stack:pop_repeat(
Stack,
N
),
gleam@result:'try'(
gleam@yielder:fold(
gleam@yielder:range(1, Index + 1),
{ok, Stack@1},
fun(Accumulator, _) ->
gleam@result:'try'(
Accumulator,
fun(Stack@2) ->
{Stack@3, _} = gwr@exec@stack:pop_while(
Stack@2,
fun gwr@exec@stack:is_value/1
),
case gwr@exec@stack:pop(
Stack@3
) of
{Stack@4,
{some,
{label_entry,
_}}} ->
{ok, Stack@4};
{_, Anything_else} ->
_pipe@10 = gwr@exec@trap:make(
invalid_state
),
_pipe@11 = gwr@exec@trap:add_message(
_pipe@10,
<<"expected the top of the stack to contain a label but got "/utf8,
(gleam@string:inspect(
Anything_else
))/binary>>
),
gwr@exec@trap:to_error(
_pipe@11
)
end
end
)
end
),
fun(Stack@5) ->
Stack@6 = gwr@exec@stack:push(
Stack@5,
begin
_pipe@12 = Values,
lists:reverse(_pipe@12)
end
),
{ok,
{Stack@6,
Store,
{some,
{branch,
erlang:element(
3,
Label
)}}}}
end
)
end
)
end
)
end
)
end
).
-file("src/gwr/exec.gleam", 1324).
-spec evaluate_br_if(gwr@exec@stack:stack(), gwr@spec:store(), integer()) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
evaluate_br_if(Stack, Store, Index) ->
case gwr@exec@stack:pop(Stack) of
{Stack@1, {some, {value_entry, {integer32_value, C}}}} ->
case C /= 0 of
true ->
evaluate_br(Stack@1, Store, Index);
false ->
{ok, {Stack@1, Store, none}}
end;
_ ->
_pipe = gwr@exec@trap:make(invalid_state),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
<<"expected the top of the stack to contain an i32 value"/utf8>>
),
gwr@exec@trap:to_error(_pipe@1)
end.
-file("src/gwr/exec.gleam", 1458).
-spec exit_with_label(gwr@exec@stack:stack(), gwr@spec:label()) -> {ok,
gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
exit_with_label(Stack, Label) ->
{Stack@1, Values} = gwr@exec@stack:pop_while(
Stack,
fun gwr@exec@stack:is_value/1
),
gleam@result:'try'(case gwr@exec@stack:pop(Stack@1) of
{Stack@2, {some, {label_entry, Some_label}}} when Some_label =:= Label ->
{ok, Stack@2};
{_, Anything_else} ->
_pipe = gwr@exec@trap:make(invalid_state),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
<<<<<<"expected the label "/utf8,
(gleam@string:inspect(Label))/binary>>/binary,
" pushed to the stack before execution but got "/utf8>>/binary,
(gleam@string:inspect(Anything_else))/binary>>
),
gwr@exec@trap:to_error(_pipe@1)
end, fun(Stack@3) ->
{ok,
gwr@exec@stack:push(
Stack@3,
begin
_pipe@2 = Values,
lists:reverse(_pipe@2)
end
)}
end).
-file("src/gwr/exec.gleam", 1167).
-spec unwind_stack(gwr@exec@stack:stack()) -> {ok, gwr@exec@stack:stack()} |
{error, gwr@exec@trap:trap()}.
unwind_stack(Stack) ->
case gwr@exec@stack:get_current_label(Stack) of
{ok, Label} ->
gleam@result:'try'(
exit_with_label(Stack, Label),
fun(Stack@1) -> unwind_stack(Stack@1) end
);
{error, _} ->
{ok, Stack}
end.
-file("src/gwr/exec.gleam", 1662).
-spec expand_block_type(gwr@spec:frame_state(), gwr@spec:block_type()) -> {ok,
gwr@spec:function_type()} |
{error, gwr@exec@trap:trap()}.
expand_block_type(Framestate, Block_type) ->
case Block_type of
{type_index_block, Index} ->
_pipe = erlang:element(2, erlang:element(3, Framestate)),
_pipe@1 = gleam@list:take(_pipe, Index + 1),
_pipe@2 = gleam@list:last(_pipe@1),
gleam@result:replace_error(
_pipe@2,
begin
_pipe@3 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@3,
<<<<"couldn't find the function type with index \""/utf8,
(erlang:integer_to_binary(Index))/binary>>/binary,
"\""/utf8>>
)
end
);
{value_type_block, {some, Valtype}} ->
{ok, {function_type, [], [Valtype]}};
{value_type_block, none} ->
{ok, {function_type, [], []}}
end.
-file("src/gwr/exec.gleam", 1061).
-spec evaluate_call(gwr@exec@stack:stack(), gwr@spec:store(), integer()) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store()}} |
{error, gwr@exec@trap:trap()}.
evaluate_call(Stack, Store, Index) ->
gleam@result:'try'(
begin
_pipe = gwr@exec@stack:get_current_frame(Stack),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the current frame"/utf8>>
)
end
)
end,
fun(Frame) ->
gleam@result:'try'(
begin
_pipe@2 = gleam_stdlib:map_get(
erlang:element(
3,
erlang:element(3, erlang:element(3, Frame))
),
Index
),
gleam@result:replace_error(
_pipe@2,
begin
_pipe@3 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@3,
<<"couldn't find the address of the function with index "/utf8,
(erlang:integer_to_binary(Index))/binary>>
)
end
)
end,
fun(Address) -> evaluate_invoke(Stack, Store, Address) end
)
end
).
-file("src/gwr/exec.gleam", 1090).
-spec evaluate_invoke(
gwr@exec@stack:stack(),
gwr@spec:store(),
gwr@spec:address()
) -> {ok, {gwr@exec@stack:stack(), gwr@spec:store()}} |
{error, gwr@exec@trap:trap()}.
evaluate_invoke(Stack, Store, Address) ->
gleam@result:'try'(
begin
_pipe = gleam_stdlib:map_get(erlang:element(2, Store), Address),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't find the function instance with address "/utf8,
(address_to_string(Address))/binary>>
)
end
)
end,
fun(Function_instance) -> case Function_instance of
{host_function_instance, _, _} ->
_pipe@2 = gwr@exec@trap:make(bad_argument),
_pipe@3 = gwr@exec@trap:add_message(
_pipe@2,
<<"@TODO: call host function"/utf8>>
),
gwr@exec@trap:to_error(_pipe@3);
{web_assembly_function_instance,
Function_type,
Function_module_instance,
Function_code} ->
N = erlang:length(erlang:element(2, Function_type)),
M = erlang:length(erlang:element(3, Function_type)),
Function_locals_types = erlang:element(3, Function_code),
Function_instructions = erlang:element(4, Function_code),
Count_of_values_on_top = gwr@exec@stack:count_on_top(
Stack,
fun gwr@exec@stack:is_value/1
),
gleam@bool:guard(
Count_of_values_on_top < N,
begin
_pipe@4 = gwr@exec@trap:make(invalid_state),
_pipe@5 = gwr@exec@trap:add_message(
_pipe@4,
<<<<<<"expected the top of the stack to contains "/utf8,
(erlang:integer_to_binary(N))/binary>>/binary,
" values but got "/utf8>>/binary,
(erlang:integer_to_binary(
Count_of_values_on_top
))/binary>>
),
gwr@exec@trap:to_error(_pipe@5)
end,
fun() ->
{Stack@1, Values} = gwr@exec@stack:pop_repeat(
Stack,
N
),
Values@1 = begin
_pipe@6 = gleam@list:map(
Values,
fun gwr@exec@stack:to_value/1
),
_pipe@7 = gleam@result:values(_pipe@6),
lists:reverse(_pipe@7)
end,
Framestate = {frame_state,
begin
_pipe@8 = Values@1,
_pipe@9 = lists:append(
_pipe@8,
gleam@list:map(
Function_locals_types,
fun get_default_value_for_type/1
)
),
_pipe@10 = gleam@list:index_map(
_pipe@9,
fun(X, I) -> {I, X} end
),
maps:from_list(_pipe@10)
end,
Function_module_instance},
evaluate_with_frame(
Stack@1,
Store,
{frame, M, Framestate},
Function_instructions
)
end
)
end end
).
-file("src/gwr/exec.gleam", 1177).
-spec evaluate_with_frame(
gwr@exec@stack:stack(),
gwr@spec:store(),
gwr@spec:frame(),
list(gwr@spec:instruction())
) -> {ok, {gwr@exec@stack:stack(), gwr@spec:store()}} |
{error, gwr@exec@trap:trap()}.
evaluate_with_frame(Stack, Store, Frame, Instructions) ->
Stack@1 = gwr@exec@stack:push(Stack, [{activation_entry, Frame}]),
Label = {label, erlang:element(2, Frame), []},
gleam@result:'try'(
enter_with_label(Stack@1, Store, Label, Instructions, []),
fun(_use0) ->
{Stack@2, Store@1, Jump} = _use0,
case Jump of
{some, return} ->
{ok, {Stack@2, Store@1}};
_ ->
gleam@result:'try'(
unwind_stack(Stack@2),
fun(Stack@3) ->
gleam@result:'try'(
begin
_pipe = gwr@exec@stack:get_current_frame(
Stack@3
),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = gwr@exec@trap:make(
invalid_state
),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the current frame"/utf8>>
)
end
)
end,
fun(Frame@1) ->
N = erlang:element(2, Frame@1),
Count_of_values_on_top = gwr@exec@stack:count_on_top(
Stack@3,
fun gwr@exec@stack:is_value/1
),
gleam@bool:guard(
Count_of_values_on_top /= N,
begin
_pipe@2 = gwr@exec@trap:make(
invalid_state
),
_pipe@3 = gwr@exec@trap:add_message(
_pipe@2,
<<<<<<"expected the top of the stack to contains "/utf8,
(erlang:integer_to_binary(
N
))/binary>>/binary,
" values but got "/utf8>>/binary,
(erlang:integer_to_binary(
Count_of_values_on_top
))/binary>>
),
gwr@exec@trap:to_error(_pipe@3)
end,
fun() ->
{Stack@4, Values} = gwr@exec@stack:pop_repeat(
Stack@3,
N
),
gleam@bool:guard(
gwr@exec@stack:peek(Stack@4) /= {some,
{activation_entry, Frame@1}},
begin
_pipe@4 = gwr@exec@trap:make(
invalid_state
),
_pipe@5 = gwr@exec@trap:add_message(
_pipe@4,
<<"expected the current frame to be on the top of the stack"/utf8>>
),
gwr@exec@trap:to_error(
_pipe@5
)
end,
fun() ->
{Stack@5, _} = gwr@exec@stack:pop(
Stack@4
),
Stack@6 = gwr@exec@stack:push(
Stack@5,
begin
_pipe@6 = Values,
lists:reverse(
_pipe@6
)
end
),
{ok, {Stack@6, Store@1}}
end
)
end
)
end
)
end
)
end
end
).
-file("src/gwr/exec.gleam", 1441).
-spec enter_with_label(
gwr@exec@stack:stack(),
gwr@spec:store(),
gwr@spec:label(),
list(gwr@spec:instruction()),
list(gwr@exec@stack:stack_entry())
) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
enter_with_label(Stack, Store, Label, Instructions, Parameters) ->
evaluate_expression(
gwr@exec@stack:push(
Stack,
begin
_pipe = [{label_entry, Label}],
lists:append(_pipe, Parameters)
end
),
Store,
Instructions
).
-file("src/gwr/exec.gleam", 1484).
-spec evaluate_expression(
gwr@exec@stack:stack(),
gwr@spec:store(),
list(gwr@spec:instruction())
) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
evaluate_expression(Stack, Store, Instructions) ->
case Instructions of
[] ->
{ok, {Stack, Store, none}};
_ ->
gleam@result:'try'(
begin
_pipe = gleam@list:first(Instructions),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = gwr@exec@trap:make(unknown),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the current instruction"/utf8>>
)
end
)
end,
fun(Instruction) -> gleam@result:'try'(case Instruction of
no_op ->
{ok, {Stack, Store, none}};
unreachable ->
_pipe@2 = gwr@exec@trap:make(unreachable),
gwr@exec@trap:to_error(_pipe@2);
'end' ->
{ok, {Stack, Store, none}};
{block, Block_type, Instructions@1} ->
evaluate_block(
Stack,
Store,
Block_type,
Instructions@1
);
{'if', Block_type@1, Instructions@2, Else_} ->
evaluate_if_else(
Stack,
Store,
Block_type@1,
Instructions@2,
Else_
);
{loop, Block_type@2, Instructions@3} ->
evaluate_loop(
Stack,
Store,
Block_type@2,
Instructions@3
);
{br, Index} ->
evaluate_br(Stack, Store, Index);
{br_if, Index@1} ->
evaluate_br_if(Stack, Store, Index@1);
return ->
_pipe@3 = evaluate_return(Stack),
gleam@result:map(
_pipe@3,
fun(X) ->
{erlang:element(1, X),
Store,
erlang:element(2, X)}
end
);
{call, Index@2} ->
_pipe@4 = evaluate_call(Stack, Store, Index@2),
gleam@result:map(
_pipe@4,
fun(X@1) ->
{erlang:element(1, X@1),
erlang:element(2, X@1),
none}
end
);
_ ->
gleam@result:map(case Instruction of
{local_get, Index@3} ->
evaluate_local_get(Stack, Index@3);
{local_set, Index@4} ->
evaluate_local_set(Stack, Index@4);
{local_tee, Index@5} ->
evaluate_local_tee(Stack, Index@5);
{i32_const, Value} ->
evaluate_const(
Stack,
integer32,
{integer_const_value, Value}
);
{i64_const, Value@1} ->
evaluate_const(
Stack,
integer64,
{integer_const_value, Value@1}
);
i32_add ->
evaluate_iadd(Stack, integer32);
i64_add ->
evaluate_iadd(Stack, integer64);
i32_sub ->
evaluate_isub(Stack, integer32);
i64_sub ->
evaluate_isub(Stack, integer64);
i32_mul ->
evaluate_imul(Stack, integer32);
i64_mul ->
evaluate_imul(Stack, integer64);
i32_div_u ->
evaluate_idiv_u(Stack, integer32);
i64_div_u ->
evaluate_idiv_u(Stack, integer64);
i32_div_s ->
evaluate_idiv_s(Stack, integer32);
i64_div_s ->
evaluate_idiv_s(Stack, integer64);
i32_rem_u ->
evaluate_irem_u(Stack, integer32);
i64_rem_u ->
evaluate_irem_u(Stack, integer64);
i32_rem_s ->
evaluate_irem_s(Stack, integer32);
i64_rem_s ->
evaluate_irem_s(Stack, integer64);
i32_and ->
evaluate_iand(Stack, integer32);
i64_and ->
evaluate_iand(Stack, integer64);
i32_or ->
evaluate_ior(Stack, integer32);
i64_or ->
evaluate_ior(Stack, integer64);
i32_xor ->
evaluate_ixor(Stack, integer32);
i64_xor ->
evaluate_ixor(Stack, integer64);
i32_shl ->
evaluate_ishl(Stack, integer32);
i64_shl ->
evaluate_ishl(Stack, integer64);
i32_shr_u ->
evaluate_ishr_u(Stack, integer32);
i64_shr_u ->
evaluate_ishr_u(Stack, integer64);
i32_shr_s ->
evaluate_ishr_s(Stack, integer32);
i64_shr_s ->
evaluate_ishr_s(Stack, integer64);
i32_rotl ->
evaluate_irotl(Stack, integer32);
i64_rotl ->
evaluate_irotl(Stack, integer64);
i32_rotr ->
evaluate_irotr(Stack, integer32);
i64_rotr ->
evaluate_irotr(Stack, integer64);
i32_clz ->
evaluate_iclz(Stack, integer32);
i64_clz ->
evaluate_iclz(Stack, integer64);
i32_ctz ->
evaluate_ictz(Stack, integer32);
i64_ctz ->
evaluate_ictz(Stack, integer64);
i32_popcnt ->
evaluate_ipopcnt(Stack, integer32);
i64_popcnt ->
evaluate_ipopcnt(Stack, integer64);
i32_eqz ->
evaluate_ieqz(Stack, integer32);
i64_eqz ->
evaluate_ieqz(Stack, integer64);
i32_eq ->
evaluate_ieq(Stack, integer32);
i64_eq ->
evaluate_ieq(Stack, integer64);
i32_ne ->
evaluate_ine(Stack, integer32);
i64_ne ->
evaluate_ine(Stack, integer64);
i32_lt_u ->
evaluate_ilt_u(Stack, integer32);
i64_lt_u ->
evaluate_ilt_u(Stack, integer64);
i32_lt_s ->
evaluate_ilt_s(Stack, integer32);
i64_lt_s ->
evaluate_ilt_s(Stack, integer64);
i32_gt_u ->
evaluate_igt_u(Stack, integer32);
i64_gt_u ->
evaluate_igt_u(Stack, integer64);
i32_gt_s ->
evaluate_igt_s(Stack, integer32);
i64_gt_s ->
evaluate_igt_s(Stack, integer64);
i32_le_u ->
evaluate_ile_u(Stack, integer32);
i64_le_u ->
evaluate_ile_u(Stack, integer64);
i32_le_s ->
evaluate_ile_s(Stack, integer32);
i64_le_s ->
evaluate_ile_s(Stack, integer64);
i32_ge_u ->
evaluate_ige_u(Stack, integer32);
i64_ge_u ->
evaluate_ige_u(Stack, integer64);
i32_ge_s ->
evaluate_ige_s(Stack, integer32);
i64_ge_s ->
evaluate_ige_s(Stack, integer64);
i32_extend8_s ->
evaluate_iextend8_s(
Stack,
integer32
);
i64_extend8_s ->
evaluate_iextend8_s(
Stack,
integer64
);
i32_extend16_s ->
evaluate_iextend16_s(
Stack,
integer32
);
i64_extend16_s ->
evaluate_iextend16_s(
Stack,
integer64
);
i64_extend32_s ->
evaluate_iextend32_s(
Stack,
integer64
);
Unknown ->
_pipe@5 = gwr@exec@trap:make(
bad_argument
),
_pipe@6 = gwr@exec@trap:add_message(
_pipe@5,
<<<<"attempt to execute an unknown or unimplemented instruction \""/utf8,
(gleam@string:inspect(
Unknown
))/binary>>/binary,
"\""/utf8>>
),
gwr@exec@trap:to_error(_pipe@6)
end, fun(Stack@1) ->
{Stack@1, Store, none}
end)
end, fun(_use0) ->
{Stack@2, Store@1, Jump} = _use0,
case Jump of
{some, return} ->
{ok, {Stack@2, Store@1, Jump}};
{some, {branch, Instructions@4}} ->
evaluate_expression(
Stack@2,
Store@1,
Instructions@4
);
none ->
evaluate_expression(
Stack@2,
Store@1,
begin
_pipe@7 = Instructions,
gleam@list:drop(_pipe@7, 1)
end
)
end
end) end
)
end.
-file("src/gwr/exec.gleam", 110).
-spec invoke(state(), gwr@spec:address(), list(gwr@spec:value())) -> {ok,
{state(), list(gwr@spec:value())}} |
{error, gwr@exec@trap:trap()}.
invoke(State, Address, Arguments) ->
Stack = gwr@exec@stack:push(
erlang:element(3, State),
begin
_pipe = Arguments,
gleam@list:map(_pipe, fun(X) -> {value_entry, X} end)
end
),
gleam@result:'try'(
evaluate_invoke(Stack, erlang:element(4, State), Address),
fun(_use0) ->
{Stack@1, Store} = _use0,
{Stack@2, Values} = gwr@exec@stack:pop_while(
Stack@1,
fun gwr@exec@stack:is_value/1
),
Results = begin
_pipe@1 = gleam@list:map(Values, fun gwr@exec@stack:to_value/1),
_pipe@2 = gleam@result:values(_pipe@1),
lists:reverse(_pipe@2)
end,
{ok, {{state, erlang:element(2, State), Stack@2, Store}, Results}}
end
).
-file("src/gwr/exec.gleam", 1351).
-spec evaluate_loop(
gwr@exec@stack:stack(),
gwr@spec:store(),
gwr@spec:block_type(),
list(gwr@spec:instruction())
) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
evaluate_loop(Stack, Store, Block_type, Instructions) ->
gleam@result:'try'(
begin
_pipe = gwr@exec@stack:get_current_frame(Stack),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the current frame"/utf8>>
)
end
)
end,
fun(Frame) ->
gleam@result:'try'(
expand_block_type(erlang:element(3, Frame), Block_type),
fun(Function_type) ->
M = erlang:length(erlang:element(2, Function_type)),
Label = {label, M, [{loop, Block_type, Instructions}]},
Count_of_values_on_top = gwr@exec@stack:count_on_top(
Stack,
fun gwr@exec@stack:is_value/1
),
gleam@bool:guard(
Count_of_values_on_top < M,
begin
_pipe@2 = gwr@exec@trap:make(invalid_state),
_pipe@3 = gwr@exec@trap:add_message(
_pipe@2,
<<<<<<"expected the top of the stack to contains at least "/utf8,
(erlang:integer_to_binary(M))/binary>>/binary,
" values but got "/utf8>>/binary,
(erlang:integer_to_binary(
Count_of_values_on_top
))/binary>>
),
gwr@exec@trap:to_error(_pipe@3)
end,
fun() ->
{Stack@1, Values} = gwr@exec@stack:pop_repeat(
Stack,
M
),
enter_with_label(
Stack@1,
Store,
Label,
Instructions,
begin
_pipe@4 = Values,
lists:reverse(_pipe@4)
end
)
end
)
end
)
end
).
-file("src/gwr/exec.gleam", 1397).
-spec evaluate_block(
gwr@exec@stack:stack(),
gwr@spec:store(),
gwr@spec:block_type(),
list(gwr@spec:instruction())
) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
evaluate_block(Stack, Store, Block_type, Instructions) ->
gleam@result:'try'(
begin
_pipe = gwr@exec@stack:get_current_frame(Stack),
gleam@result:replace_error(
_pipe,
begin
_pipe@1 = gwr@exec@trap:make(invalid_state),
gwr@exec@trap:add_message(
_pipe@1,
<<"couldn't get the current frame"/utf8>>
)
end
)
end,
fun(Frame) ->
gleam@result:'try'(
expand_block_type(erlang:element(3, Frame), Block_type),
fun(Function_type) ->
M = erlang:length(erlang:element(2, Function_type)),
N = erlang:length(erlang:element(3, Function_type)),
Label = {label, N, []},
Count_of_values_on_top = gwr@exec@stack:count_on_top(
Stack,
fun gwr@exec@stack:is_value/1
),
gleam@bool:guard(
Count_of_values_on_top < M,
begin
_pipe@2 = gwr@exec@trap:make(invalid_state),
_pipe@3 = gwr@exec@trap:add_message(
_pipe@2,
<<<<<<"expected the top of the stack to contains at least "/utf8,
(erlang:integer_to_binary(M))/binary>>/binary,
" values but got "/utf8>>/binary,
(erlang:integer_to_binary(
Count_of_values_on_top
))/binary>>
),
gwr@exec@trap:to_error(_pipe@3)
end,
fun() ->
{Stack@1, Values} = gwr@exec@stack:pop_repeat(
Stack,
M
),
enter_with_label(
Stack@1,
Store,
Label,
Instructions,
begin
_pipe@4 = Values,
lists:reverse(_pipe@4)
end
)
end
)
end
)
end
).
-file("src/gwr/exec.gleam", 1620).
-spec evaluate_if_else(
gwr@exec@stack:stack(),
gwr@spec:store(),
gwr@spec:block_type(),
list(gwr@spec:instruction()),
gleam@option:option(gwr@spec:instruction())
) -> {ok,
{gwr@exec@stack:stack(), gwr@spec:store(), gleam@option:option(jump())}} |
{error, gwr@exec@trap:trap()}.
evaluate_if_else(Stack, Store, Block_type, If_instructions, Else_) ->
case gwr@exec@stack:pop_as(Stack, fun gwr@exec@stack:to_value/1) of
{ok, {Stack@1, {integer32_value, C}}} ->
case C /= 0 of
true ->
evaluate_block(Stack@1, Store, Block_type, If_instructions);
false ->
case Else_ of
{some, {'else', Else_instructions}} ->
evaluate_block(
Stack@1,
Store,
Block_type,
Else_instructions
);
none ->
{ok, {Stack@1, Store, none}};
Anything_else ->
_pipe = gwr@exec@trap:make(bad_argument),
_pipe@1 = gwr@exec@trap:add_message(
_pipe,
<<"illegal instruction in the Else's field "/utf8,
(gleam@string:inspect(Anything_else))/binary>>
),
gwr@exec@trap:to_error(_pipe@1)
end
end;
Anything_else@1 ->
_pipe@2 = gwr@exec@trap:make(invalid_state),
_pipe@3 = gwr@exec@trap:add_message(
_pipe@2,
<<"expected the If's continuation flag but got "/utf8,
(gleam@string:inspect(Anything_else@1))/binary>>
),
gwr@exec@trap:to_error(_pipe@3)
end.