Added more Lua environment features
Package library:
* Added a simulation of the Lua 5.1 package library.
* Removed mw.import(), replaced it with a package loader. Packages can be
retrieved from the wiki, using require('Module:Foo'), or from files
distributed with Scribunto, using require('foo'). The "Module:" prefix allows
for source compatibility with existing Lua code.
* Added a couple of libraries from LuaForge: luabit and stringtools.
* Made fetchModuleFromParser() return null on error instead of throwing an
exception, to more easily support the desired behaviour of the package loader,
which needs to return null on error.
* Renamed mw.setupEnvironment() to mw.setup() since it is setting up things
other than the environment now.
* In MWServer:handleRegisterLibrary(), remove the feature which interprets dots
in library names, since LuaSandbox doesn't support this.
Improved module isolation and related refactoring:
* Expose restricted versions of getfenv() and setfenv() to user Lua code.
Requires luasandbox r114952.
* Don't cache the export list returned by module execution for later function
calls. This breaks isolation of #invoke calls, since the local variables are
persistent.
* Removed ScribuntoFunctionBase and its children, since it doesn't really have
a purpose if it can't cache anything. Instead, invoke functions using a module
method called invoke().
* Removed Module::initialize(), replaced it with a validate() function. This is
a more elegant interface and works better with the new module caching scheme.
* Use a Status object for the return value of Engine::validate() instead of an
array. Use the formatting facilities of the Status class.
Other:
* Removed "too many returns" error, doesn't fit in with Lua conventions.
* Use the standalone engine by default, so that the extension will work without
configuration for more people.
* Added an accessor for $engine->interpreter
* Fix mw.clone() to correctly clone metatables
* If the standalone interpreter exits due to an error, there are some contexts
where the initial error will be caught and ignored, and the user will see the
error from checkValid() instead. In this case, rethrow the original error for
a more informative message.
* Load mw.lua into the initial standalone environment, to reduce code
duplication between mw.lua and MWServer.lua.
* Fixed a bug in Scribunto_LuaStandaloneInterpreter::handleCall() for functions
that return no results.
* Fixed a bug in encodeLuaVar() for strings with "\r". Added test case.
* In MWServer.lua, don't call error() for internal errors, instead just print
the error and exit. This avoids a protocol violation when an error is
encountered from within handleCall().
* Added lots of documentation. Lua doc comments are in LuaDoc format.
Change-Id: Ie2fd572c362bedf02f45d3fa5352a5280e034740
2012-04-18 03:46:18 +00:00
|
|
|
--[[---------------
|
|
|
|
LuaBit v0.4
|
|
|
|
-------------------
|
|
|
|
a bitwise operation lib for lua.
|
|
|
|
|
|
|
|
http://luaforge.net/projects/bit/
|
|
|
|
|
|
|
|
How to use:
|
|
|
|
-------------------
|
|
|
|
bit.bnot(n) -- bitwise not (~n)
|
|
|
|
bit.band(m, n) -- bitwise and (m & n)
|
|
|
|
bit.bor(m, n) -- bitwise or (m | n)
|
|
|
|
bit.bxor(m, n) -- bitwise xor (m ^ n)
|
|
|
|
bit.brshift(n, bits) -- right shift (n >> bits)
|
|
|
|
bit.blshift(n, bits) -- left shift (n << bits)
|
|
|
|
bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>)
|
|
|
|
|
|
|
|
Please note that bit.brshift and bit.blshift only support number within
|
|
|
|
32 bits.
|
|
|
|
|
|
|
|
2 utility functions are provided too:
|
|
|
|
bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence)
|
|
|
|
-- high bits first
|
|
|
|
bit.tonumb(bit_tbl) -- convert a bit table into a number
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
Under the MIT license.
|
|
|
|
|
|
|
|
copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
|
2013-02-21 03:41:29 +00:00
|
|
|
|
|
|
|
2013-02-20: Brad Jorsch: Fix to not try messing with globals, doesn't work in Scribunto
|
Added more Lua environment features
Package library:
* Added a simulation of the Lua 5.1 package library.
* Removed mw.import(), replaced it with a package loader. Packages can be
retrieved from the wiki, using require('Module:Foo'), or from files
distributed with Scribunto, using require('foo'). The "Module:" prefix allows
for source compatibility with existing Lua code.
* Added a couple of libraries from LuaForge: luabit and stringtools.
* Made fetchModuleFromParser() return null on error instead of throwing an
exception, to more easily support the desired behaviour of the package loader,
which needs to return null on error.
* Renamed mw.setupEnvironment() to mw.setup() since it is setting up things
other than the environment now.
* In MWServer:handleRegisterLibrary(), remove the feature which interprets dots
in library names, since LuaSandbox doesn't support this.
Improved module isolation and related refactoring:
* Expose restricted versions of getfenv() and setfenv() to user Lua code.
Requires luasandbox r114952.
* Don't cache the export list returned by module execution for later function
calls. This breaks isolation of #invoke calls, since the local variables are
persistent.
* Removed ScribuntoFunctionBase and its children, since it doesn't really have
a purpose if it can't cache anything. Instead, invoke functions using a module
method called invoke().
* Removed Module::initialize(), replaced it with a validate() function. This is
a more elegant interface and works better with the new module caching scheme.
* Use a Status object for the return value of Engine::validate() instead of an
array. Use the formatting facilities of the Status class.
Other:
* Removed "too many returns" error, doesn't fit in with Lua conventions.
* Use the standalone engine by default, so that the extension will work without
configuration for more people.
* Added an accessor for $engine->interpreter
* Fix mw.clone() to correctly clone metatables
* If the standalone interpreter exits due to an error, there are some contexts
where the initial error will be caught and ignored, and the user will see the
error from checkValid() instead. In this case, rethrow the original error for
a more informative message.
* Load mw.lua into the initial standalone environment, to reduce code
duplication between mw.lua and MWServer.lua.
* Fixed a bug in Scribunto_LuaStandaloneInterpreter::handleCall() for functions
that return no results.
* Fixed a bug in encodeLuaVar() for strings with "\r". Added test case.
* In MWServer.lua, don't call error() for internal errors, instead just print
the error and exit. This avoids a protocol violation when an error is
encountered from within handleCall().
* Added lots of documentation. Lua doc comments are in LuaDoc format.
Change-Id: Ie2fd572c362bedf02f45d3fa5352a5280e034740
2012-04-18 03:46:18 +00:00
|
|
|
--]]---------------
|
|
|
|
|
|
|
|
do
|
|
|
|
|
|
|
|
------------------------
|
|
|
|
-- bit lib implementions
|
|
|
|
|
|
|
|
local function check_int(n)
|
|
|
|
-- checking not float
|
|
|
|
if(n - math.floor(n) > 0) then
|
|
|
|
error("trying to use bitwise operation on non-integer!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function to_bits(n)
|
|
|
|
check_int(n)
|
|
|
|
if(n < 0) then
|
|
|
|
-- negative
|
|
|
|
return to_bits(bit.bnot(math.abs(n)) + 1)
|
|
|
|
end
|
|
|
|
-- to bits table
|
|
|
|
local tbl = {}
|
|
|
|
local cnt = 1
|
|
|
|
while (n > 0) do
|
|
|
|
local last = math.mod(n,2)
|
|
|
|
if(last == 1) then
|
|
|
|
tbl[cnt] = 1
|
|
|
|
else
|
|
|
|
tbl[cnt] = 0
|
|
|
|
end
|
|
|
|
n = (n-last)/2
|
|
|
|
cnt = cnt + 1
|
|
|
|
end
|
|
|
|
|
|
|
|
return tbl
|
|
|
|
end
|
|
|
|
|
|
|
|
local function tbl_to_number(tbl)
|
|
|
|
local n = table.getn(tbl)
|
|
|
|
|
|
|
|
local rslt = 0
|
|
|
|
local power = 1
|
|
|
|
for i = 1, n do
|
|
|
|
rslt = rslt + tbl[i]*power
|
|
|
|
power = power*2
|
|
|
|
end
|
|
|
|
|
|
|
|
return rslt
|
|
|
|
end
|
|
|
|
|
|
|
|
local function expand(tbl_m, tbl_n)
|
|
|
|
local big = {}
|
|
|
|
local small = {}
|
|
|
|
if(table.getn(tbl_m) > table.getn(tbl_n)) then
|
|
|
|
big = tbl_m
|
|
|
|
small = tbl_n
|
|
|
|
else
|
|
|
|
big = tbl_n
|
|
|
|
small = tbl_m
|
|
|
|
end
|
|
|
|
-- expand small
|
|
|
|
for i = table.getn(small) + 1, table.getn(big) do
|
|
|
|
small[i] = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
local function bit_or(m, n)
|
|
|
|
local tbl_m = to_bits(m)
|
|
|
|
local tbl_n = to_bits(n)
|
|
|
|
expand(tbl_m, tbl_n)
|
|
|
|
|
|
|
|
local tbl = {}
|
|
|
|
local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
|
|
|
|
for i = 1, rslt do
|
|
|
|
if(tbl_m[i]== 0 and tbl_n[i] == 0) then
|
|
|
|
tbl[i] = 0
|
|
|
|
else
|
|
|
|
tbl[i] = 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return tbl_to_number(tbl)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function bit_and(m, n)
|
|
|
|
local tbl_m = to_bits(m)
|
|
|
|
local tbl_n = to_bits(n)
|
|
|
|
expand(tbl_m, tbl_n)
|
|
|
|
|
|
|
|
local tbl = {}
|
|
|
|
local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
|
|
|
|
for i = 1, rslt do
|
|
|
|
if(tbl_m[i]== 0 or tbl_n[i] == 0) then
|
|
|
|
tbl[i] = 0
|
|
|
|
else
|
|
|
|
tbl[i] = 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return tbl_to_number(tbl)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function bit_not(n)
|
|
|
|
|
|
|
|
local tbl = to_bits(n)
|
|
|
|
local size = math.max(table.getn(tbl), 32)
|
|
|
|
for i = 1, size do
|
|
|
|
if(tbl[i] == 1) then
|
|
|
|
tbl[i] = 0
|
|
|
|
else
|
|
|
|
tbl[i] = 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return tbl_to_number(tbl)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function bit_xor(m, n)
|
|
|
|
local tbl_m = to_bits(m)
|
|
|
|
local tbl_n = to_bits(n)
|
|
|
|
expand(tbl_m, tbl_n)
|
|
|
|
|
|
|
|
local tbl = {}
|
|
|
|
local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
|
|
|
|
for i = 1, rslt do
|
|
|
|
if(tbl_m[i] ~= tbl_n[i]) then
|
|
|
|
tbl[i] = 1
|
|
|
|
else
|
|
|
|
tbl[i] = 0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--table.foreach(tbl, print)
|
|
|
|
|
|
|
|
return tbl_to_number(tbl)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function bit_rshift(n, bits)
|
|
|
|
check_int(n)
|
|
|
|
|
|
|
|
local high_bit = 0
|
|
|
|
if(n < 0) then
|
|
|
|
-- negative
|
|
|
|
n = bit_not(math.abs(n)) + 1
|
|
|
|
high_bit = 2147483648 -- 0x80000000
|
|
|
|
end
|
|
|
|
|
|
|
|
for i=1, bits do
|
|
|
|
n = n/2
|
|
|
|
n = bit_or(math.floor(n), high_bit)
|
|
|
|
end
|
|
|
|
return math.floor(n)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- logic rightshift assures zero filling shift
|
|
|
|
local function bit_logic_rshift(n, bits)
|
|
|
|
check_int(n)
|
|
|
|
if(n < 0) then
|
|
|
|
-- negative
|
|
|
|
n = bit_not(math.abs(n)) + 1
|
|
|
|
end
|
|
|
|
for i=1, bits do
|
|
|
|
n = n/2
|
|
|
|
end
|
|
|
|
return math.floor(n)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function bit_lshift(n, bits)
|
|
|
|
check_int(n)
|
|
|
|
|
|
|
|
if(n < 0) then
|
|
|
|
-- negative
|
|
|
|
n = bit_not(math.abs(n)) + 1
|
|
|
|
end
|
|
|
|
|
|
|
|
for i=1, bits do
|
|
|
|
n = n*2
|
|
|
|
end
|
|
|
|
return bit_and(n, 4294967295) -- 0xFFFFFFFF
|
|
|
|
end
|
|
|
|
|
|
|
|
local function bit_xor2(m, n)
|
|
|
|
local rhs = bit_or(bit_not(m), bit_not(n))
|
|
|
|
local lhs = bit_or(m, n)
|
|
|
|
local rslt = bit_and(lhs, rhs)
|
|
|
|
return rslt
|
|
|
|
end
|
|
|
|
|
|
|
|
--------------------
|
|
|
|
-- bit lib interface
|
|
|
|
|
2013-02-21 03:41:29 +00:00
|
|
|
local bit = {
|
Added more Lua environment features
Package library:
* Added a simulation of the Lua 5.1 package library.
* Removed mw.import(), replaced it with a package loader. Packages can be
retrieved from the wiki, using require('Module:Foo'), or from files
distributed with Scribunto, using require('foo'). The "Module:" prefix allows
for source compatibility with existing Lua code.
* Added a couple of libraries from LuaForge: luabit and stringtools.
* Made fetchModuleFromParser() return null on error instead of throwing an
exception, to more easily support the desired behaviour of the package loader,
which needs to return null on error.
* Renamed mw.setupEnvironment() to mw.setup() since it is setting up things
other than the environment now.
* In MWServer:handleRegisterLibrary(), remove the feature which interprets dots
in library names, since LuaSandbox doesn't support this.
Improved module isolation and related refactoring:
* Expose restricted versions of getfenv() and setfenv() to user Lua code.
Requires luasandbox r114952.
* Don't cache the export list returned by module execution for later function
calls. This breaks isolation of #invoke calls, since the local variables are
persistent.
* Removed ScribuntoFunctionBase and its children, since it doesn't really have
a purpose if it can't cache anything. Instead, invoke functions using a module
method called invoke().
* Removed Module::initialize(), replaced it with a validate() function. This is
a more elegant interface and works better with the new module caching scheme.
* Use a Status object for the return value of Engine::validate() instead of an
array. Use the formatting facilities of the Status class.
Other:
* Removed "too many returns" error, doesn't fit in with Lua conventions.
* Use the standalone engine by default, so that the extension will work without
configuration for more people.
* Added an accessor for $engine->interpreter
* Fix mw.clone() to correctly clone metatables
* If the standalone interpreter exits due to an error, there are some contexts
where the initial error will be caught and ignored, and the user will see the
error from checkValid() instead. In this case, rethrow the original error for
a more informative message.
* Load mw.lua into the initial standalone environment, to reduce code
duplication between mw.lua and MWServer.lua.
* Fixed a bug in Scribunto_LuaStandaloneInterpreter::handleCall() for functions
that return no results.
* Fixed a bug in encodeLuaVar() for strings with "\r". Added test case.
* In MWServer.lua, don't call error() for internal errors, instead just print
the error and exit. This avoids a protocol violation when an error is
encountered from within handleCall().
* Added lots of documentation. Lua doc comments are in LuaDoc format.
Change-Id: Ie2fd572c362bedf02f45d3fa5352a5280e034740
2012-04-18 03:46:18 +00:00
|
|
|
-- bit operations
|
|
|
|
bnot = bit_not,
|
|
|
|
band = bit_and,
|
|
|
|
bor = bit_or,
|
|
|
|
bxor = bit_xor,
|
|
|
|
brshift = bit_rshift,
|
|
|
|
blshift = bit_lshift,
|
|
|
|
bxor2 = bit_xor2,
|
|
|
|
blogic_rshift = bit_logic_rshift,
|
|
|
|
|
|
|
|
-- utility func
|
|
|
|
tobits = to_bits,
|
|
|
|
tonumb = tbl_to_number,
|
|
|
|
}
|
|
|
|
|
2013-02-21 03:41:29 +00:00
|
|
|
return bit
|
|
|
|
|
Added more Lua environment features
Package library:
* Added a simulation of the Lua 5.1 package library.
* Removed mw.import(), replaced it with a package loader. Packages can be
retrieved from the wiki, using require('Module:Foo'), or from files
distributed with Scribunto, using require('foo'). The "Module:" prefix allows
for source compatibility with existing Lua code.
* Added a couple of libraries from LuaForge: luabit and stringtools.
* Made fetchModuleFromParser() return null on error instead of throwing an
exception, to more easily support the desired behaviour of the package loader,
which needs to return null on error.
* Renamed mw.setupEnvironment() to mw.setup() since it is setting up things
other than the environment now.
* In MWServer:handleRegisterLibrary(), remove the feature which interprets dots
in library names, since LuaSandbox doesn't support this.
Improved module isolation and related refactoring:
* Expose restricted versions of getfenv() and setfenv() to user Lua code.
Requires luasandbox r114952.
* Don't cache the export list returned by module execution for later function
calls. This breaks isolation of #invoke calls, since the local variables are
persistent.
* Removed ScribuntoFunctionBase and its children, since it doesn't really have
a purpose if it can't cache anything. Instead, invoke functions using a module
method called invoke().
* Removed Module::initialize(), replaced it with a validate() function. This is
a more elegant interface and works better with the new module caching scheme.
* Use a Status object for the return value of Engine::validate() instead of an
array. Use the formatting facilities of the Status class.
Other:
* Removed "too many returns" error, doesn't fit in with Lua conventions.
* Use the standalone engine by default, so that the extension will work without
configuration for more people.
* Added an accessor for $engine->interpreter
* Fix mw.clone() to correctly clone metatables
* If the standalone interpreter exits due to an error, there are some contexts
where the initial error will be caught and ignored, and the user will see the
error from checkValid() instead. In this case, rethrow the original error for
a more informative message.
* Load mw.lua into the initial standalone environment, to reduce code
duplication between mw.lua and MWServer.lua.
* Fixed a bug in Scribunto_LuaStandaloneInterpreter::handleCall() for functions
that return no results.
* Fixed a bug in encodeLuaVar() for strings with "\r". Added test case.
* In MWServer.lua, don't call error() for internal errors, instead just print
the error and exit. This avoids a protocol violation when an error is
encountered from within handleCall().
* Added lots of documentation. Lua doc comments are in LuaDoc format.
Change-Id: Ie2fd572c362bedf02f45d3fa5352a5280e034740
2012-04-18 03:46:18 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
--[[
|
|
|
|
for i = 1, 100 do
|
|
|
|
for j = 1, 100 do
|
|
|
|
if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then
|
|
|
|
error("bit.xor failed.")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
--]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|