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
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,11 @@ rescue
e.line # => 2
e.source # => "<eval>" (chunk name)

# e.message is a formatted, colorized frame (ANSI codes elided here):
#
# Lua runtime error: Runtime Error
#
# at <eval>:2:
# Lua runtime error: at <eval>:2:
#
# runtime error: something went wrong
e.message
Exception.message(e)
end
```

Expand Down
24 changes: 12 additions & 12 deletions lib/lua.ex
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ defmodule Lua do
bounds tail recursion too — including loops that PUC-Lua would run indefinitely. Leave the
default `:infinity` if you rely on unbounded tail recursion.

iex> lua = Lua.new(max_call_depth: 10)
iex> {[false, message], _lua} = Lua.eval!(lua, "local function f() return f() end return pcall(f)")
iex> message =~ "stack overflow"
true
iex> lua = Lua.new(max_call_depth: 10)
iex> {[false, message], _lua} = Lua.eval!(lua, "local function f() return f() end return pcall(f)")
iex> message =~ "stack overflow"
true

* `:max_string_bytes` - (default 256 MiB) ceiling for any single string the VM will build,
whether via `..`, `string.rep`, or a `load` reader. An oversized result raises a catchable
Expand All @@ -112,10 +112,10 @@ defmodule Lua do
heap cap mid-allocation, where the kill depends on garbage-collection timing rather than
a deterministic refusal.

iex> lua = Lua.new(max_string_bytes: 1024)
iex> {[false, message], _lua} = Lua.eval!(lua, "return pcall(string.rep, \\"x\\", 2048)")
iex> message =~ "resulting string too large"
true
iex> lua = Lua.new(max_string_bytes: 1024)
iex> {[false, message], _lua} = Lua.eval!(lua, "return pcall(string.rep, 'x', 2048)")
iex> message =~ "resulting string too large"
true

* `:max_instructions` - (default `:infinity`) caps the number of VM instructions a single
evaluation may execute. When a script exceeds this budget, a catchable
Expand All @@ -125,10 +125,10 @@ defmodule Lua do
back-edges and call boundaries, so the default `:infinity` path carries no per-instruction
cost. The budget is fresh per top-level evaluation and recoverable via `pcall`.

iex> lua = Lua.new(max_instructions: 1000)
iex> {[false, message], _lua} = Lua.eval!(lua, "return pcall(function() while true do end end)")
iex> message =~ "instruction budget exceeded"
true
iex> lua = Lua.new(max_instructions: 1000)
iex> {[false, message], _lua} = Lua.eval!(lua, "return pcall(function() while true do end end)")
iex> message =~ "instruction budget exceeded"
true
"""
@spec new(keyword()) :: t()
def new(opts \\ []) do
Expand Down
12 changes: 6 additions & 6 deletions website/lib/website_web/snippets.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ defmodule DemoWeb.Snippets do

lua = Lua.new()

{:error, err} =
Lua.eval(lua, "return os.execute('rm -rf /')")

# err.message =~ "attempted to call"
# Calling a sandboxed function raises.
Lua.eval!(lua, "return os.execute('rm -rf /')")
# ** (Lua.RuntimeException) Lua runtime error:
# os.execute(_) is sandboxed
"""
},
%{
Expand All @@ -75,7 +75,7 @@ defmodule DemoWeb.Snippets do
lua = Lua.new() |> Lua.load_api(Agent.Tools)

# The model emits Lua. You run it. Done.
{:ok, {results, _}} = Lua.eval(lua, llm_script)
{results, _lua} = Lua.eval!(lua, llm_script)
"""
}
]
Expand Down Expand Up @@ -179,7 +179,7 @@ defmodule DemoWeb.Snippets do

# The agent emits Lua. You run it. It can only
# do what you exposed -- nothing else.
{:ok, {result, _lua}} = Lua.eval(lua, agent_script)
{result, _lua} = Lua.eval!(lua, agent_script)
"""

@tvlabs_remote_api """
Expand Down
Loading