Skip to content

Commit

Permalink
Fix string.char() recording with no arguments.
Browse files Browse the repository at this point in the history
(cherry picked from commit dfa692b)

`string.char()` call without arguments yields an empty string. JIT
recording machinery doesn’t handle this case. Each recording of a fast
function expects 1 result by default. Hence, when return from this call
is recorded, some garbage value is considered as a result to be yielded.
It is loaded from the corresponding slot as an IR with `IRT_NUM` type.
It leads to assertion failure in `rec_check_slots()`, when a next
bytecode is recorded, because type of TValue on the stack (`LJ_STR`)
isn't the same as IR (and TRef) type.

This patch handles the case without arguments by the loading of IR with
empty string reference as a result value.

Sergey Kaplun:
* added the description and the test for the problem

Resolves tarantool/tarantool#6371
Part of tarantool/tarantool#6548

Reviewed-by: Sergey Ostanevich <sergos@tarantool.org>
Reviewed-by: Igor Munkin <imun@tarantool.org>
Signed-off-by: Igor Munkin <imun@tarantool.org>
  • Loading branch information
Mike Pall authored and igormunkin committed Jun 16, 2022
1 parent d8655b0 commit e3ccc70
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions test/tarantool-tests/gh-6371-string-char-no-arg.test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
local tap = require('tap')

-- Test file to demonstrate assertion after `string.char()`
-- recording.
-- See also, https://github.com/tarantool/tarantool/issues/6371.

local test = tap.test('gh-6371-string-char-no-arg')
-- XXX: Number of loop iterations.
-- * 1 -- instruction becomes hot.
-- * 2 -- recording of the loop body.
-- * 3 -- required for trace finalization, but this iteration
-- runs the generated mcode and reproduces the issue.
local NTEST = 3
test:plan(NTEST)

-- Storage for the results to avoid trace aborting by `test:ok()`.
-- XXX: Use `table.new()` here to avoid side exit from trace by
-- table resizing.
local results = require('table.new')(3, 0)
jit.opt.start('hotloop=1')
for _ = 1, NTEST do
table.insert(results, string.char())
end

for i = 1, NTEST do
test:ok(results[i] == '', 'correct recording of string.char() without args')
end

os.exit(test:check() and 0 or 1)

0 comments on commit e3ccc70

Please sign in to comment.