Hi, Sergey,
thanks for the patch! LGTM with a minor comment. See below.
<snipped>
diff --git a/test/tarantool-tests/lj-1234-err-in-record-concat.test.lua b/test/tarantool-tests/lj-1234-err-in-record-concat.test.lua
new file mode 100644
index 00000000..9abaeba5
--- /dev/null
+++ b/test/tarantool-tests/lj-1234-err-in-record-concat.test.lua
@@ -0,0 +1,43 @@
+local tap = require('tap')
+
+-- Test file to demonstrate the crash during the concat recording
+-- if it throws an error.
+-- See also: https://github.com/LuaJIT/LuaJIT/issues/1234.
+
+local test = tap.test('lj-1234-err-in-record-concat'):skipcond({
+ ['Test requires JIT enabled'] = not jit.status(),
+})
+
+test:plan(2)
+
+jit.opt.start('hotloop=1')
+
+local __concat = function(v1, v2)
+ return tostring(v1) .. tostring(v2)
+end
+
+-- Need to use metamethod call in the concat recording.
+debug.setmetatable(nil, {
I propose to add a comment that explain why `nil` is used here.
+ __concat = __concat,
+})
+
+local function test_concat_p()
+ local counter = 0
+ while counter < 1 do
+ counter = counter + 1
+ -- The first result is placed on the Lua stack before the
+ -- error is raised. When the error is raised, it is handled by
+ -- the trace recorder, but since neither `rec_cat()` nor
+ -- `lj_record_ret()` restore the Lua stack (before the patch),
+ -- it becomes unbalanced after the instruction recording
+ -- attempt.
+ local _ = {} .. (nil .. nil)
+ end
+end
+
+local result, errmsg = pcall(test_concat_p)
+
+test:ok(not result, 'the error is raised')
+test:like(errmsg, 'attempt to concatenate a table value', 'correct error')
+
+test:done(true)