1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
local isJit = (tostring(assert):match('builtin') ~= nil)
if not isJit then
return function() end
end
-- pre-load the ffi module, such that it becomes part of the environment
-- and Busted will not try to GC and reload it. The ffi is not suited
-- for that and will occasionally segfault if done so.
local ffi = require "ffi"
-- patching assumes;
-- * first parameter to be a unique key to identify repeated calls
-- * only a single return value
local function patch_with_return_value(func_name)
local original = ffi[func_name]
local original_store = {}
ffi[func_name] = function (primary, ...)
if original_store[primary] then
return original_store[primary]
end
local success, result, err = pcall(original, primary, ...)
if not success then
-- hard error was thrown
error(result, 2)
end
if not result then
-- soft error was returned
return result, err
end
-- it worked, store and return
original_store[primary] = result
return result
end
end
local function patch_without_return_value(func_name)
local original = ffi[func_name]
local original_store = {}
ffi[func_name] = function (primary, ...)
if original_store[primary] then
return
end
local success, result = pcall(original, primary, ...)
if not success then
-- hard error was thrown
error(result, 2)
end
-- store and return
original_store[primary] = true
return result
end
end
return function()
patch_without_return_value("cdef")
patch_with_return_value("typeof")
patch_with_return_value("metatype")
patch_with_return_value("load")
end
|