Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions lib/ash_lua/encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,8 @@ defmodule AshLua.Encoder do
def encode_result({:native_func, _}), do: %{"opaque" => "function"}
def encode_result({:lua_closure, _, _}), do: %{"opaque" => "function"}
def encode_result({:compiled_closure, _, _}), do: %{"opaque" => "function"}
def encode_result({:funref, _, _}), do: %{"opaque" => "function"}
def encode_result({:erl_func, _}), do: %{"opaque" => "function"}
def encode_result({:erl_mfa, _, _, _}), do: %{"opaque" => "function"}
def encode_result({:tref, _}), do: %{"opaque" => "table_reference"}
def encode_result({:udref, _}), do: %{"opaque" => "userdata"}
def encode_result({:usdref, _}), do: %{"opaque" => "userdata"}
# The Lua VM can also return the decoded shape `{module, function, arity_or_undefined}`
# for built-in callables.
def encode_result({m, f, a})
when is_atom(m) and is_atom(f) and (is_integer(a) or is_atom(a)),
do: %{"opaque" => "function"}

# An installed Erlang/Elixir callback (e.g. our overridden `print`) decodes
# as a bare Erlang fun on the way back out. Same opaque marker.
Expand Down
13 changes: 7 additions & 6 deletions lib/ash_lua/eval.ex
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,11 @@ defmodule AshLua.Eval do
}}
end

defp extract_structured_error(%Lua.RuntimeException{original: original, state: state}) do
case {raised_value(original), lua_state(original, state)} do
# The raised Lua value and the VM state at the point of failure both live on
# the wrapped VM exception (`:original`); the outer `Lua.RuntimeException`
# never carries state itself.
defp extract_structured_error(%Lua.RuntimeException{original: original}) do
case {raised_value(original), vm_state(original)} do
{nil, _state} -> nil
{_value, nil} -> nil
{value, lua_state} -> value |> safe_decode(lua_state) |> normalize_error_table()
Expand All @@ -204,13 +207,11 @@ defmodule AshLua.Eval do

defp extract_structured_error(_), do: nil

defp raised_value({:assert_error, value}), do: value
defp raised_value({:error_call, [value | _]}), do: value
defp raised_value(error) when is_struct(error), do: Map.get(error, :value)
defp raised_value(_), do: nil

defp lua_state(original, nil) when is_struct(original), do: Map.get(original, :state)
defp lua_state(_original, state), do: state
defp vm_state(error) when is_struct(error), do: Map.get(error, :state)
defp vm_state(_), do: nil

defp safe_decode(value, state) do
Lua.decode!(%Lua{state: state}, value)
Expand Down
38 changes: 12 additions & 26 deletions lib/ash_lua/runtime.ex
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,6 @@ defmodule AshLua.Runtime do
defp format_print_arg(_state, {:native_func, _}), do: "<function>"
defp format_print_arg(_state, {:lua_closure, _, _}), do: "<function>"
defp format_print_arg(_state, {:compiled_closure, _, _}), do: "<function>"
defp format_print_arg(_state, {:funref, _, _}), do: "<function>"
defp format_print_arg(_state, {:erl_func, _}), do: "<function>"
defp format_print_arg(_state, {:erl_mfa, _, _, _}), do: "<function>"
defp format_print_arg(_state, {:usdref, _}), do: "<userdata>"
defp format_print_arg(_state, {:udref, _}), do: "<userdata>"
defp format_print_arg(_state, value), do: inspect(value)

Expand Down Expand Up @@ -381,7 +377,7 @@ defmodule AshLua.Runtime do
{:body_ok, values}

{:error, reason, new_state} ->
# Stash both the state AND the original Lua error tuple. The
# Stash both the state AND the original Lua exception. The
# data layer's rollback wrapper calls `Mnesia.abort/1` on our
# `{:error, reason}` return; Mnesia's transaction catch then
# `Exception.format_exit/1`s the tuple to a string before
Expand Down Expand Up @@ -421,7 +417,7 @@ defmodule AshLua.Runtime do

{{:error, _ash_error}, lua_error} when not is_nil(lua_error) ->
# Rollback was triggered by a Lua-side error; we stashed the
# original tuple before Mnesia's exit-formatting wrapped it.
# original exception before Mnesia's exit-formatting wrapped it.
encode_lua_transaction_error(new_state, lua_error)

{{:error, ash_error}, _} ->
Expand All @@ -445,31 +441,21 @@ defmodule AshLua.Runtime do
end
end

defp encode_lua_transaction_error(state, {:assert_error, value}) do
encode_lua_transaction_error_body(state, value)
end

defp encode_lua_transaction_error(state, {:error_call, [value | _]}) do
encode_lua_transaction_error_body(state, value)
# `Lua.call_function/3` reports failures as `%Lua.RuntimeException{}`; the
# raised Lua value (string, table ref, ...) is on `:value`. The exception
# itself carries no VM state, so refs are decoded against the post-call
# `%Lua{}` we stashed through the message channel.
defp encode_lua_transaction_error(state, %Lua.RuntimeException{value: nil}) do
encode_lua_transaction_error(state, :unknown)
end

# `utils.transaction.rollback` raises with the encoded value directly, so
# the captured error reason can be a bare `{:tref, _}` rather than one of
# the wrapped shapes above.
defp encode_lua_transaction_error(state, {:tref, _} = tref) do
encode_lua_transaction_error_body(state, tref)
end

defp encode_lua_transaction_error(state, message) when is_binary(message) do
defp encode_lua_transaction_error(state, %Lua.RuntimeException{value: message})
when is_binary(message) do
encode_lua_transaction_error_body(state, strip_lua_location(message))
end

defp encode_lua_transaction_error(state, error) when is_struct(error) do
case {Map.get(error, :value), Map.get(error, :state)} do
{nil, _state} -> encode_lua_transaction_error(state, :unknown)
{_value, nil} -> encode_lua_transaction_error(state, :unknown)
{value, lua_state} -> encode_lua_transaction_error_body(%Lua{state: lua_state}, value)
end
defp encode_lua_transaction_error(state, %Lua.RuntimeException{value: value}) do
encode_lua_transaction_error_body(state, value)
end

defp encode_lua_transaction_error(state, _other) do
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ defmodule AshLua.MixProject do
defp deps do
[
{:ash, ash_version("~> 3.25 and >= 3.25.2")},
{:lua, "~> 1.0.0-rc"},
{:lua, "~> 1.0"},
{:jason, "~> 1.2"},
{:igniter, "~> 0.6", optional: true},
{:spark, ">= 2.2.10"},
Expand Down
Loading