bcsave.lua 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. ----------------------------------------------------------------------------
  2. -- LuaJIT module to save/list bytecode.
  3. --
  4. -- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
  5. -- Released under the MIT/X license. See Copyright Notice in luajit.h
  6. ----------------------------------------------------------------------------
  7. --
  8. -- This module saves or lists the bytecode for an input file.
  9. -- It's run by the -b command line option.
  10. --
  11. ------------------------------------------------------------------------------
  12. -- Cache some library functions and objects.
  13. local jit = require("jit")
  14. assert(jit.version_num == 20000, "LuaJIT core/library version mismatch")
  15. ------------------------------------------------------------------------------
  16. local function usage()
  17. io.stderr:write[[
  18. Save LuaJIT bytecode: luajit -b[options] input output
  19. -l Only list bytecode.
  20. -s Strip debug info (default).
  21. -g Keep debug info.
  22. -e chunk Use chunk string as input.
  23. -- Stop handling options.
  24. - Use stdin as input and/or stdout as output.
  25. ]]
  26. os.exit(1)
  27. end
  28. local function readfile(input)
  29. if type(input) == "function" then return input end
  30. if input == "-" then input = nil end
  31. local f, err = loadfile(input)
  32. if not f then
  33. io.stderr:write("luajit: ", err, "\n")
  34. os.exit(1)
  35. end
  36. return f
  37. end
  38. local function readstring(input)
  39. local f, err = loadstring(input)
  40. if not f then
  41. io.stderr:write("luajit: ", err, "\n")
  42. os.exit(1)
  43. end
  44. return f
  45. end
  46. local function savefile(name, mode)
  47. if name == "-" then return io.stdout end
  48. local fp, err = io.open(name, mode)
  49. if not fp then
  50. io.stderr:write("luajit: cannot write ", err, "\n")
  51. os.exit(1)
  52. end
  53. return fp
  54. end
  55. ------------------------------------------------------------------------------
  56. local function bclist(input, output)
  57. local f = readfile(input)
  58. require("jit.bc").dump(f, savefile(output, "w"), true)
  59. end
  60. local function bcsave(input, output, strip)
  61. local f = readfile(input)
  62. local s = string.dump(f, strip)
  63. local fp = savefile(output, "wb")
  64. local ok, err = fp:write(s)
  65. if ok and output ~= "-" then ok, err = fp:close() end
  66. if not ok then
  67. io.stderr:write("luajit: cannot write ", arg[2], ": ", err, "\n")
  68. os.exit(1)
  69. end
  70. end
  71. local function docmd(...)
  72. local arg = {...}
  73. local n = 1
  74. local list = false
  75. local strip = true
  76. while n <= #arg do
  77. local a = arg[n]
  78. if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then
  79. if a == "--" then table.remove(arg, n); break end
  80. for m=2,#a do
  81. local opt = string.sub(a, m, m)
  82. if opt == "l" then
  83. list = true
  84. elseif opt == "s" then
  85. strip = true
  86. elseif opt == "g" then
  87. strip = false
  88. elseif opt == "e" then
  89. if n ~= 1 or #arg < 2 or m ~= #a then usage() end
  90. arg[2] = readstring(arg[2])
  91. else
  92. usage()
  93. end
  94. end
  95. table.remove(arg, n)
  96. else
  97. n = n + 1
  98. end
  99. end
  100. if list then
  101. if #arg == 0 or #arg > 2 then usage() end
  102. bclist(arg[1], arg[2] or "-")
  103. else
  104. if #arg ~= 2 then usage() end
  105. bcsave(arg[1], arg[2], strip)
  106. end
  107. end
  108. ------------------------------------------------------------------------------
  109. -- Public module functions.
  110. module(...)
  111. start = docmd -- Process -b command line option.