181 Commits

Author SHA1 Message Date
UnlegitDqrk
67429a7a31 Fixed issue: #55 2026-03-02 15:49:57 +01:00
UnlegitDqrk
139af3f28b Implemented issue: #19 2026-03-02 15:42:55 +01:00
UnlegitDqrk
33d745d667 Implemented issue: #47 2026-03-02 15:36:05 +01:00
UnlegitDqrk
06c74072be Fixed issue: #47 2026-03-02 15:31:22 +01:00
UnlegitDqrk
63edacbb5f Fixed issue: #51 2026-03-02 15:28:31 +01:00
UnlegitDqrk
7aea99d650 Implemented issue: #56 2026-03-02 14:58:31 +01:00
UnlegitDqrk
921606b93f Implemented issue: #65 2026-03-02 14:48:30 +01:00
UnlegitDqrk
5f11997446 Implemented issue: #67 2026-03-02 14:44:54 +01:00
UnlegitDqrk
c735ac67a0 Fixed issue: #68 2026-03-02 14:37:27 +01:00
UnlegitDqrk
7f7185aa08 Fixed issue: #70 2026-03-02 14:27:11 +01:00
UnlegitDqrk
39ff4f204d Fixed issue: #71 2026-03-02 14:22:54 +01:00
UnlegitDqrk
9cb10a390f Fixed issue: #74 2026-03-02 14:14:14 +01:00
UnlegitDqrk
c60991a33c Fixed issue: #75 2026-03-02 14:11:08 +01:00
UnlegitDqrk
c8fdc62495 Fixed issue: #81 2026-03-02 14:07:54 +01:00
UnlegitDqrk
ff4033cad4 Implemented issue: #82 2026-03-02 13:48:14 +01:00
UnlegitDqrk
572fd95692 Fixed issue: #86 2026-03-02 13:31:34 +01:00
UnlegitDqrk
db392c4763 Implemented issue: #87 2026-03-02 13:10:29 +01:00
UnlegitDqrk
98437da1fa Fixed issue: #96 2026-03-02 12:52:07 +01:00
UnlegitDqrk
85ed36de51 Fixed issue: #101 2026-03-02 11:58:39 +01:00
UnlegitDqrk
1d3459e0d3 Started with upgrading to Lua 5.3 2026-03-01 21:42:37 +01:00
UnlegitDqrk
493b055a26 Started with upgrading to Lua 5.3 2026-03-01 21:42:19 +01:00
UnlegitDqrk
01a8bd944e Fixed issue: #108 2026-03-01 19:57:26 +01:00
UnlegitDqrk
4c2add3832 Fixed issue: #94 2026-03-01 19:36:19 +01:00
UnlegitDqrk
364dbecb17 Fixed issue: Invalid escape sequences in string literals not raising errors (e.g. \q) 2026-03-01 19:11:18 +01:00
UnlegitDqrk
86e4d78761 Fixed issue: tonumber("-") returns 0 #6 2026-03-01 18:47:22 +01:00
UnlegitDqrk
7338475ae4 Fixed LuaJC not writing java package to bytecode correctly 2026-03-01 13:11:33 +01:00
UnlegitDqrk
01739d4e77 Pull request: MAXSTACK = 1024;LUAI_MAXVARS = 1024; #46 2026-03-01 13:08:19 +01:00
UnlegitDqrk
37b68d4d85 Pull request: Reduce allocations per LuaClosure call #76 2026-03-01 13:06:19 +01:00
UnlegitDqrk
f30c4c3bec Fixed varargs invocation from luajava 2026-03-01 13:04:22 +01:00
UnlegitDqrk
d0c84972dd fixed bug: invoke java variable parameter type method problem 2026-03-01 13:01:18 +01:00
UnlegitDqrk
068451886d fixed bug: invoke overload method disorder 2026-03-01 12:59:23 +01:00
UnlegitDqrk
ba3d1d8ef9 Added missed Classes 2026-03-01 12:57:18 +01:00
UnlegitDqrk
405fd633fd Added missed Classes 2026-03-01 12:56:55 +01:00
UnlegitDqrk
f087e87806 Updated to Java 25 2026-03-01 12:50:46 +01:00
UnlegitDqrk
95ea3d84b6 Added licenses 2026-03-01 12:40:00 +01:00
UnlegitDqrk
f40e89e19c Implemented Support of Java 21 VirtualThread 2026-03-01 12:39:42 +01:00
40831d0f2d Update README.md 2026-03-01 10:33:16 +00:00
bba6df42fd Update README.md 2026-03-01 10:29:43 +00:00
3df6dc9e96 Update README.md 2026-03-01 10:29:28 +00:00
Enyby
daf3da94e3 Fix #66: Broken license link. 2020-04-01 19:36:00 +03:00
Enyby
30e60a883e Create LICENSE
Source: https://web.archive.org/web/20140514153921/http://sourceforge.net/dbimage.php?id=196142
2020-04-01 19:31:39 +03:00
Enyby
27edcc9a92 Fix possible error in rare cases in LuaTable:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
2019-12-29 16:46:58 +02:00
Enyby
d6737c0bb3 Improve work with weak keys.
```
for _, m in ipairs({'', 'k', 'kv', 'v'}) do
	print('test', m)
	a = {}; setmetatable(a, {__mode = m});
	a[1], a[2], a[3] = {}, {}, {};
	for k, v in pairs(a) do
		print(k, v)
	end
end
print('ok')
```
2019-12-16 15:31:13 +02:00
Enyby
d201bc3012 Fix work with weak tables.
```
a = {}; setmetatable(a, {__mode = 'vk'});
a[1], a[2], a[3] = {}, {}, {};
for k, v in pairs(a) do
	print(k, v)
end
print('ok')
```
2019-12-15 20:39:26 +02:00
Enyby
ca64666242 Fix metamethods for compare with numbers.
```
t = {}
t.__lt = function (a,b,c)
  collectgarbage()
  assert(c == nil)
  if type(a) == 'table' then a = a.x end
  if type(b) == 'table' then b = b.x end
 return a<b, "dummy"
end

function Op(x) return setmetatable({x=x}, t) end

local function test ()
  assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1)))
  assert(not(1 < Op(1)) and (Op(1) < 2) and not(2 < Op(1)))
  assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a')))
  assert(not('a' < Op('a')) and (Op('a') < 'b') and not(Op('b') < Op('a')))
  assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1)))
  assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a')))
  assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1)))
  assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a')))
  assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1)))
  assert((1 >= Op(1)) and not(1 >= Op(2)) and (Op(2) >= 1))
  assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a')))
  assert(('a' >= Op('a')) and not(Op('a') >= 'b') and (Op('b') >= Op('a')))
end

test()
```
2019-11-11 02:47:19 +02:00
Enyby
725cf89b6f Fix metamethods for compare with string. 2019-11-11 02:29:20 +02:00
Enyby
da0b06555a Fix pattern error message. 2019-11-09 23:26:48 +02:00
Enyby
ee2d5284e7 Fix '%b' pattern error message. 2019-11-09 23:25:58 +02:00
Enyby
0f0ec4bf7b Add check for too complex patterns.
```
-- bug since 2.5 (C-stack overflow)
do
  local function f (size)
    local s = string.rep("a", size)
    local p = string.rep(".?", size)
    return pcall(string.match, s, p)
  end
  local r, m = f(80)
  assert(r and #m == 80)
  r, m = f(200000)
  assert(not r and string.find(m, "too complex"), tostring(r)..", "..tostring(m))
end
```
2019-11-09 23:25:07 +02:00
Enyby
5813d56f89 Improve error messages for invalid capture index. 2019-11-09 23:21:39 +02:00
Enyby
8c42c4712b Fix empty matches in patterns.
```
do   -- new (5.3.3) semantics for empty matches
  assert(string.gsub("a b cd", " *", "-") == "-a-b-c-d-")

  local res = ""
  local sub = "a  \nbc\t\td"
  local i = 1
  for p, e in string.gmatch(sub, "()%s*()") do
    res = res .. string.sub(sub, i, p - 1) .. "-"
    i = e
  end
  assert(res == "-a-b-c-d-")
end
```
2019-11-09 23:20:06 +02:00
Enyby
6bc8fd6b1b Fix numeric for add order. 2019-11-09 23:12:31 +02:00
Enyby
bf663878cb Add support for metatags to table lib methods: sort, insert, remove, unpack.
```
do   -- testing table library with metamethods
  local function test (proxy, t)
    for i = 1, 10 do
      table.insert(proxy, 1, i)
    end
    assert(#proxy == 10 and #t == 10, tostring(#proxy)..'; '..tostring(#t))
    for i = 1, 10 do
      assert(t[i] == 11 - i)
    end
    table.sort(proxy)
    for i = 1, 10 do
      assert(t[i] == i and proxy[i] == i, i..': '..tostring(proxy[i])..'; '..tostring(t[i]))
    end
    assert(table.concat(proxy, ",") == "1,2,3,4,5,6,7,8,9,10")
    for i = 1, 8 do
      assert(table.remove(proxy, 1) == i)
    end
    assert(#proxy == 2 and #t == 2)
    local a, b, c = table.unpack(proxy)
    assert(a == 9 and b == 10 and c == nil)
  end

  -- all virtual
  local t = {}
  local proxy = setmetatable({}, {
    __len = function () return #t end,
    __index = t,
    __newindex = t,
  })
  test(proxy, t)

  -- only __newindex
  local count = 0
  t = setmetatable({}, {
    __newindex = function (t,k,v) count = count + 1; rawset(t,k,v) end})
  test(t, t)
  assert(count == 10)   -- after first 10, all other sets are not new

  -- no __newindex
  t = setmetatable({}, {
    __index = function (_,k) return k + 1 end,
    __len = function (_) return 5 end})
  assert(table.concat(t, ";") == "2;3;4;5;6")

end

function check (a, f)
  f = f or function (x,y) return x<y end;
  for n = #a, 2, -1 do
    local cmp = f(a[n], a[n-1])
    if cmp then print(tostring(a)..'\n'..n..': "'..tostring(a[n])..'" < "'..tostring(a[n-1])..'"') end
    assert(not cmp)
  end
end

for b = 1, 2 do
	a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
	     "Oct", "Nov", "Dec"}
	if b == 2 then a[15] = 'Aaa' a[14] = 'Iii' a[13] = 'Mmm' end
	print(#a)
	table.sort(a)
	check(a)
end
```
2019-11-04 07:57:49 +02:00
Enyby
e120008f9b Validate table.remove pos. 2019-11-03 16:08:01 +02:00
Enyby
9a20aa8077 Check pos bounds for table.insert. 2019-11-03 15:55:32 +02:00
Enyby
99f21b6277 Speed up table.sort. 2019-11-03 14:03:53 +02:00
Enyby
53bd4bf71f Fix compiler Bug{
what = [[label between local definitions can mix-up their initializations]],
report = [[Karel Tuma, 2016/03/01]],
since = [[5.2]],
fix = nil,
example = [[
do
  local k = 0
  local x
  ::foo::
  local y       -- should be reset to nil after goto, but it is not
  assert(not y)
  y = true
  k = k + 1
  if k < 2 then goto foo end
end
]],
patch = [[
--- lparser.c	2015/11/02 16:09:30	2.149
+++ lparser.c	2016/03/03 12:03:37
@@ -1226,7 +1226,7 @@
   checkrepeated(fs, ll, label);  /* check for repeated labels */
   checknext(ls, TK_DBCOLON);  /* skip double colon */
   /* create new entry for this label */
-  l = newlabelentry(ls, ll, label, line, fs->pc);
+  l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
   skipnoopstat(ls);  /* skip other no-op statements */
   if (block_follow(ls, 0)) {  /* label is last no-op statement in the block? */
     /* assume that locals are already out of scope */
]]
}
2019-11-02 17:02:21 +02:00
Enyby
b57eb247ba Fix table.unpack. 2019-11-02 15:18:48 +02:00
Enyby
05e82f1c3f Add package.config. #49 2019-10-27 23:08:44 +02:00
Enyby
9b2f0a2805 Fix os.tmpname. 2019-10-22 07:00:21 +03:00
Enyby
ef8175050b Remove unused field. 2019-10-21 23:26:10 +03:00
Enyby
0d2aa6cc54 Switch little-endian by default as original Lua does. 2019-10-21 23:25:30 +03:00
Enyby
fe7bd07450 Fix lexer bugs.
Wrong work with spaces.
2019-10-21 10:20:06 +03:00
Enyby
f0e9348ae2 Fix lexer bugs.
Already handled by inside isalnum.
2019-10-21 10:17:26 +03:00
Enyby
22e7a8c620 Fix lexer bugs.
Already handled by case above.
2019-10-21 10:16:43 +03:00
Enyby
c8461b8128 Fix pattern classes in string lib.
```
local ref = {
}
for cl in string.gmatch('acdglpsuwxACDGLPSUWX', '.') do
	local list = ''
	for i = 0, 255 do
		if string.match(string.char(i), '%'..cl) then
			list = list..i..','
		end
	end
	if ref[cl] then
		assert(ref[cl] == list, cl..':\n'..list..'\n'..ref[cl])
	else
		print(cl..' = "'..list..'",')
	end
end

print('+')
```
2019-10-21 08:43:53 +03:00
Enyby
3a6c382570 Fix 'error' call. #60 2019-10-20 19:19:14 +03:00
Enyby
4db34780b7 Fix build error. 2019-10-20 18:43:10 +03:00
Enyby
ac3475deee Improved error messages for lib functions. 2019-10-20 07:19:34 +03:00
Enyby
af35c4d89e Improve error messages for base lib. 2019-10-20 07:17:46 +03:00
Enyby
c71f277697 Improve error messages for lib table. 2019-10-20 07:07:17 +03:00
Enyby
5fe0a3950d Improve get name for func. 2019-10-20 06:45:53 +03:00
Enyby
169202362e Fix error message for collectgarbage invalid option. 2019-10-20 00:34:54 +03:00
Enyby
5609d8c92b Add check mode for io.open. #57 2019-10-19 20:53:56 +03:00
Enyby
dbab0aed01 Fix odd varargs methods. 2019-10-14 18:33:25 +03:00
Enyby
f8d7731b56 Fix NPE on getobjname in some cases. 2019-10-14 14:12:08 +03:00
Enyby
2f5aa594bd Fix getobjname for get constant name if it stored on register. 2019-10-14 14:11:38 +03:00
Enyby
edfe1a5fde Add check for io.popen modes. 2019-10-13 06:16:21 +03:00
Enyby
6efb6f000e Improve error message for file:seek and file:setvbuf. 2019-10-13 05:58:32 +03:00
Enyby
f3b8a1eddc Fix default setvbuf size. 2019-10-12 19:12:44 +03:00
Enyby
20eca5760d Fix detect io lib read modes like file:read('*all'). 2019-10-12 17:57:37 +03:00
Enyby
3613bc0862 Add check for values passed to file:vsetbuf and file:seek. 2019-10-12 17:51:04 +03:00
Enyby
6985980572 Merge branch 'master' of https://github.com/luaj/luaj 2019-10-12 16:09:03 +03:00
Enyby
60d130cecc Fix corrupted args for io.lines and file:lines on reuse stack elements. 2019-10-12 16:08:36 +03:00
Enyby
b705eb05f4 Merge pull request #59 from Mikhael-Danilov/patch-1
Fix link
2019-10-07 21:53:17 +03:00
Mikhael-Danilov
d0bb0409a3 Fix link
Fix link to examples/android/src/android/LuajViewLuajView.java
2019-10-07 20:23:45 +03:00
Enyby
db58e1808b Fix load script from func. 2019-10-07 18:08:47 +03:00
Enyby
e2ede7f91c Fix call io.lines(nil, ...). 2019-10-07 17:11:13 +03:00
Enyby
a50deaa75c Fix raise error from io.lines and file:lines. 2019-10-07 14:52:12 +03:00
Enyby
f9f78b81da Allow read zero bytes in io lib methods. 2019-10-07 14:26:21 +03:00
Enyby
984fa30bf6 Fix read all stdin in JSE. 2019-10-07 00:25:07 +03:00
Enyby
65beda4c2b Fix read all at EOF. 2019-10-07 00:23:34 +03:00
Enyby
934a8fc57b Fix io.read(0) on EOF. 2019-10-06 23:49:04 +03:00
Enyby
832ec739ea Close not closed file on GC. #55
Relevant only for J2SE, not for J2ME.
2019-10-06 23:35:45 +03:00
Enyby
8345bee6b4 Fix io.lines and file:lines do not honor additional params. #52
Fix io.lines do not close file on EOF. #53
Improve error message for io.lines and file:lines on closed file.
2019-10-06 19:09:01 +03:00
Enyby
83f2e1d96a Fix io.read and file:read do not support '*L' format. #54 2019-10-06 18:53:15 +03:00
Enyby
14745ba76a Fix call io.read, file:read without params. 2019-10-06 18:40:31 +03:00
Enyby
c62ba1f22e File tostring respect closed. 2019-10-06 16:54:44 +03:00
Enyby
868928779f Fix rewrite io.input inside io.lines.
```
do
	local t = os.tmpname()
	local f = io.open(t, 'w')
	f:write('test')
	f:close()

	local i = io.input()
	for l in io.lines(t) do end
	local n = io.input()
	assert(n == i, tostring(n).." ~= "..tostring(i))
	os.remove(t)
	print('+')
end
```
2019-10-06 16:43:11 +03:00
Enyby
f383c27728 We not in C anymore. 2019-09-23 01:54:27 +03:00
Enyby
e7b11110a3 Raise lexerror if failed parse number as double. 2019-09-23 01:53:01 +03:00
Enyby
0fa27c3783 EOZ (-1) not a space char.
Fix bug with endless loop at not ended \z sequence.

```
local function lexerror (s, err)
  local st, msg = load('return ' .. s, '')
  if err ~= '<eof>' then err = err .. "'" end
  assert(not st and string.find(msg, "near .-" .. err))
end

lexerror("'alo \\z  \n\n", "<eof>")
```
2019-09-23 00:39:42 +03:00
Enyby
72a71e5a65 Merge branch 'master' of https://github.com/luaj/luaj 2019-09-21 07:18:37 +03:00
Enyby
6031d6b479 Fix lua error message on bad arg for 'load'. 2019-09-21 07:18:08 +03:00
Enyby
c1834733c1 Merge pull request #45 from zaoqi/patch-1
readme: fix typo
2019-08-10 02:18:32 +03:00
Zaoqi
10f88d2c31 readme: fix typo 2019-08-09 21:44:25 +08:00
Enyby
6d2deb4cb6 Fix use function as source for load call. 2019-08-05 04:07:09 +03:00
Enyby
5f52729fc9 Fix OP_JMP description. 2019-07-15 05:29:37 +03:00
Enyby
e6736857b6 Add support for OP_LOADKX. #43 2019-06-30 22:18:19 +03:00
Enyby
5c5176727a Merge branch 'master' of https://github.com/luaj/luaj 2019-05-05 17:23:27 +03:00
Enyby
7721380e20 Fix NPE on error. #40 2019-05-05 17:22:24 +03:00
Enyby
16aa199d40 Add debug info to build. 2019-05-05 17:21:25 +03:00
Enyby
177fe4e09f Fix path to build files in Readme.md 2019-03-17 03:12:52 +02:00
Enyby
a7c8a408ce Fix build bug. #33 2019-03-17 03:06:05 +02:00
Enyby
84b0dd171e Fix error messages for pass tests. 2019-03-09 23:35:22 +02:00
Enyby
898208365d Fix print for pass tests. 2019-03-09 23:18:47 +02:00
Enyby
ffb686556f Fix loadlib. 2019-03-09 23:00:28 +02:00
Enyby
6694c375c9 Fix build errors for j2me. #32 2019-03-09 17:38:32 +02:00
Enyby
e70eb5edc2 Fix build bug. #32 2019-03-09 15:49:56 +02:00
Enyby
9688d3c5fc Remove libs dependency from PackageLib. 2019-01-13 19:23:44 +02:00
Enyby
6f5af581e8 Fix string.gsub for invalid use '%' in replacement string
Check code:
```
print(pcall(load('string.gsub("test", "%S", "A%")')))
print(pcall(load('string.gsub("test", "%S", "%A")')))
```
2019-01-03 18:09:00 +02:00
Enyby
870aee2cae Improved opt methods for numbers in LuaString 2018-12-29 19:49:43 +02:00
Enyby
c2ec9edf39 Deny use NaN as index in rawset. 2018-12-24 22:34:49 +02:00
Enyby
cfb3aaca61 Fix math.min and math.max.
Now similar to native Lua and reference: `Returns the argument with the maximum value, according to the Lua operator <. (integer/float) `
2018-12-24 20:52:23 +02:00
Enyby
4105cebf1e Fix math.fmod for int values. 2018-12-24 20:37:39 +02:00
Enyby
339f004eb7 More compat with lua tests. 2018-12-24 19:30:11 +02:00
Enyby
05a604645d Fix modulo for edge cases.
Reference code:
```
for i,lhs in ipairs({-math.huge, -10.0, 0.0, 10.0, math.huge}) do
for j,rhs in ipairs({-math.huge, -10.0, 0.0, 10.0, math.huge}) do
print(lhs, rhs, lhs % rhs)
end
end
```
2018-12-24 18:30:35 +02:00
Enyby
63ead7aac7 Fix string.format for long integers. 2018-12-24 11:45:06 +02:00
Enyby
c9ba2d4bb1 Fix math.modf for inf/-inf and int values. 2018-12-23 17:48:31 +02:00
Enyby
92cee0812d Fix JSE math.log for second arg. 2018-12-23 17:06:34 +02:00
Enyby
e61e5694fa Fix string.match for empty pattern 2018-12-16 06:38:23 +02:00
Enyby
47f8d6e6fc Fix a frontier pattern match
We're not in C anymore. LuaString are not null terminated.
Also need quotes in error messages.
2018-12-11 23:44:39 +02:00
Enyby
14ac4bb7f9 Merge pull request #21 from lorenzos/patch-1
Check the type before reusing a NumberValueEntry
2018-11-02 23:11:36 +02:00
Lorenzo Stanco
b8aaaafb68 Check the type before reusing a NumberValueEntry
Fixes #20
2018-10-31 15:57:02 +01:00
Enyby
88a557033b Optimize get new stack for calls. 2018-09-20 20:14:02 +03:00
Enyby
24a8559ceb Fix make LuaString from copy. 2018-09-17 16:32:09 +03:00
Enyby
028e03e4bc Avoid synthetic methods 2018-09-16 18:49:26 +03:00
Enyby
5c1f7d2ab2 Make const final 2018-09-16 18:45:52 +03:00
Enyby
9db1254160 Avoid synthetic methods 2018-09-16 18:44:36 +03:00
Enyby
f899c709ff Remove unused var. 2018-09-16 18:43:39 +03:00
Enyby
9c9e193cc4 Make consts final. 2018-09-16 18:40:06 +03:00
Enyby
e9db487d97 Improve convert function to string. 2018-09-16 18:38:49 +03:00
Enyby
c6fe5d3ed3 Avoid synthetic methods 2018-09-16 17:15:54 +03:00
Enyby
52ab872d08 Improve rawopenfile 2018-09-16 17:11:28 +03:00
Enyby
5d3041c6be Improved get/setLocal. 2018-09-16 17:09:18 +03:00
Enyby
8d544729a8 Avoid synthetic methods. 2018-09-16 17:05:52 +03:00
Enyby
bd57dddef0 Imrove traceback build. 2018-09-16 17:03:35 +03:00
Enyby
d509e21cc6 Make static classes. 2018-09-16 17:02:24 +03:00
Enyby
5b67841232 Avoid synthetic methods 2018-09-16 16:58:51 +03:00
Enyby
bd4dac18ff Make classes static to avoid leak parent instance. 2018-09-16 16:56:53 +03:00
Enyby
e02a82ef8d Improve print. 2018-09-16 16:53:20 +03:00
Enyby
70a5086097 Make constants final. 2018-09-16 16:47:17 +03:00
Enyby
ad20f939b1 Fixed typo in JseOsLib 2018-09-16 16:46:13 +03:00
Enyby
e7058bcd6a Improved math.atan/atan2. 2018-09-16 16:44:21 +03:00
Enyby
00c7e266ba Used BufferedInputStream for JseBaseLib 2018-09-16 16:36:40 +03:00
Enyby
e75c5e2fca Fix Visitor bug. 2018-09-16 16:33:42 +03:00
Enyby
ed46675a25 Improved concat values. 2018-09-16 16:08:53 +03:00
Enyby
8fbca25dce Fixed table.unpack 2018-09-16 16:03:09 +03:00
Enyby
d0ed5b80e5 Improved error messages. 2018-09-16 15:52:14 +03:00
Enyby
9b77084109 Improved error messages. 2018-09-16 15:39:24 +03:00
Enyby
4f410fba6e Fixed metatag processing for equality. 2018-09-16 15:30:41 +03:00
Enyby
f164c1cd28 Added optional param stripDebug to string.dump 2018-09-16 15:21:16 +03:00
Enyby
63ca0f94af Removed synthetic accessors. 2018-09-16 15:13:06 +03:00
Enyby
5bd9827af1 Improve error message for string.char. 2018-09-16 15:09:36 +03:00
Enyby
0a5cccc50f Fix issue with frontier patterns #3 2018-09-16 15:02:29 +03:00
Enyby
12aded74ca Removed unused objects. 2018-09-16 10:01:39 +03:00
Enyby
48dd90f6d7 Removed unnecessary override. 2018-09-16 09:58:16 +03:00
Enyby
6333d9acf7 Merge pull request #17 from Enyby/patch-9
Fix format float numbers
2018-09-16 09:24:04 +03:00
Benjamin P. Jung
d61ed707ef Merge pull request #18 from Enyby/patch-1
Rename README.html to README.md
2018-09-15 21:40:22 +02:00
Enyby
1e521d8900 Rename README.html to README.md 2018-09-14 15:46:14 +03:00
Benjamin P. Jung
bf8ef8d1a9 Merge pull request #15 from Enyby/patch-7
Fix gmatch for pass testsuites
2018-09-14 12:13:34 +02:00
Benjamin P. Jung
69498dbb7c Merge pull request #16 from Enyby/patch-8
Fix build stack traceback in DebugLib

Fixes #7
2018-09-14 12:12:42 +02:00
Benjamin P. Jung
4cc5f4270d Merge pull request #14 from Enyby/patch-6
Fix for proper print OP_SETLIST additional opcode

Closes #7
2018-09-14 12:12:10 +02:00
Enyby
75fa98d13f Fix format float numbers
Fix bug: https://sourceforge.net/p/luaj/bugs/53/ if System support String.format or fallback to old way.
2018-09-14 02:16:42 +03:00
Enyby
a627a868d5 Fix build stack traceback in DebugLib #7
If create huge table with a lot items (> 28000) then additional op code for store `c` out of range of op codes and this loop crash.
This PR add case for OP_SETLIST for skip next op if in it stored `c`.
OP_SETLIST not AMode OP 
70cb74b4d6/src/core/org/luaj/vm2/Lua.java (L319)
70cb74b4d6/src/core/org/luaj/vm2/Lua.java (L335)
2018-09-14 02:13:21 +03:00
Enyby
f073919f64 Print any code 2018-09-14 02:09:43 +03:00
Enyby
27a1dcdd11 Fix gmatch for pass testsuites
Test suites from lua.org:
```
-- tests for gmatch
local a = 0
for i in string.gmatch('abcde', '()') do assert(i == a+1); a=i end
assert(a==6)

t = {n=0}
for w in string.gmatch("first second word", "%w+") do
      t.n=t.n+1; t[t.n] = w
end
assert(t[1] == "first" and t[2] == "second" and t[3] == "word")

t = {3, 6, 9}
for i in string.gmatch ("xuxx uu ppar r", "()(.)%2") do
  assert(i == table.remove(t, 1))
end
assert(#t == 0)

t = {}
for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23", "(%d+)%s*=%s*(%d+)") do
  t[tonumber(i)] = tonumber(j)
end
a = 0
for k,v in pairs(t) do assert(k+1 == v+0); a=a+1 end
assert(a == 3)


-- tests for `%f' (`frontiers')

assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x")
assert(string.gsub("[[]] [][] [[[[", "%f[[].", "x") == "x[]] x]x] x[[[")
assert(string.gsub("01abc45de3", "%f[%d]", ".") == ".01abc.45de.3")
assert(string.gsub("01abc45 de3x", "%f[%D]%w", ".") == "01.bc45 de3.")
assert(string.gsub("function", "%f[\1-\255]%w", ".") == ".unction")
assert(string.gsub("function", "%f[^\1-\255]", ".") == "function.")

assert(string.find("a", "%f[a]") == 1)
assert(string.find("a", "%f[^%z]") == 1)
assert(string.find("a", "%f[^%l]") == 2)
assert(string.find("aba", "%f[a%z]") == 3)
assert(string.find("aba", "%f[%z]") == 4)
assert(not string.find("aba", "%f[%l%z]"))
assert(not string.find("aba", "%f[^%l%z]"))

local i, e = string.find(" alo aalo allo", "%f[%S].-%f[%s].-%f[%S]")
assert(i == 2 and e == 5)
local k = string.match(" alo aalo allo", "%f[%S](.-%f[%s].-%f[%S])")
assert(k == 'alo ')

local a = {1, 5, 9, 14, 17,}
for k in string.gmatch("alo alo th02 is 1hat", "()%f[%w%d]") do
  assert(table.remove(a, 1) == k)
end
assert(#a == 0)
```
Code from lua:
https://www.lua.org/source/5.2/lstrlib.c.html
```
static int gmatch_aux (lua_State *L) {
  MatchState ms;
  size_t ls, lp;
  const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
  const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp);
  const char *src;
  ms.L = L;
  ms.matchdepth = MAXCCALLS;
  ms.src_init = s;
  ms.src_end = s+ls;
  ms.p_end = p + lp;
  for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
       src <= ms.src_end;
       src++) {
    const char *e;
    ms.level = 0;
    lua_assert(ms.matchdepth == MAXCCALLS);
    if ((e = match(&ms, src, p)) != NULL) {
      lua_Integer newstart = e-s;
      if (e == src) newstart++;  /* empty match? go at least one position */
      lua_pushinteger(L, newstart);
      lua_replace(L, lua_upvalueindex(3));
      return push_captures(&ms, src, e);
    }
  }
  return 0;  /* not found */
}
```
On empty match need increase string offset.
2018-09-14 02:04:56 +03:00
Enyby
b459724103 Fix for proper print OP_SETLIST additional opcode #7 2018-09-14 01:59:35 +03:00
Benjamin P. Jung
3d22990e3c Migrate CVS project to Git
* Delete .svnignore and move stuff to .gitignore
* Add note to README to show that this is an inofficial fork as of now.
* Change file suffix of README file from .html to .md for better
  Github integration and readability
2018-09-13 11:56:02 +02:00
James Roseborough
194b776317 Add synchronization to CoerceJavaToLua.COERCIONS map. 2018-09-13 11:53:24 +02:00
James Roseborough
828e4be019 Fix JsePlatform.luaMain() to provide an "arg" table in the chunk's environment. 2018-09-13 11:53:00 +02:00
613 changed files with 10839 additions and 10797 deletions

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/core"/>
<classpathentry excluding="org/luaj/vm2/luajc/antlr/|org/luaj/vm2/luajc/lst/|org/luaj/vm2/luajc/JavaCodeGenerator.java" kind="src" path="src/jse"/>
<classpathentry kind="src" path="src/jme"/>
<classpathentry kind="src" path="test/java"/>
<classpathentry kind="src" path="test/junit"/>
<classpathentry kind="src" path="test/lua"/>
<classpathentry kind="src" path="examples/jse"/>
<classpathentry kind="src" path="examples/jme"/>
<classpathentry kind="src" path="examples/lua"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="lib" path="lib/midpapi20.jar"/>
<classpathentry kind="lib" path="lib/cldcapi11.jar"/>
<classpathentry kind="lib" path="lib/bcel-5.2.jar"/>
<classpathentry kind="var" path="JRE_LIB"/>
<classpathentry kind="output" path="bin"/>
</classpath>

10
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

16
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="core" />
<module name="jme" />
<module name="jse" />
<module name="maven-example" />
</profile>
</annotationProcessing>
</component>
</project>

7
.idea/discord.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

13
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/core/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/core/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jme/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jme/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jse/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jse/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

25
.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="oac" />
<option name="name" value="oac" />
<option name="url" value="https://repo.open-autonomous-connection.org/api/packages/open-autonomous-connection/maven" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

9
.idea/luaj.iml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

18
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/examples/maven/pom.xml" />
<option value="$PROJECT_DIR$/core/pom.xml" />
<option value="$PROJECT_DIR$/jme/pom.xml" />
<option value="$PROJECT_DIR$/jse/pom.xml" />
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="25" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>luaj-vm</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2007 LuaJ. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,27 +1,30 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> # This is a fork!
<html> <div style="border: 1px dotted red; margin: 1.em 0.5em; font-weight: bold; color: red;">
This repository has been forked from https://github.com/luaj/luaj.<br />
The commit history has been converted to make sure that the original work of
James Roseborough and Ian Farmer and fork work of luaj/luaj is not lost.
</div>
<h3>Original repository fork notice:</h3>
<div style="border: 1px dotted red; margin: 1.em 0.5em; font-weight: bold; color: red;">
The original repository has been forked from the original CVS sources of Luaj.
The commit history has been converted to make sure that the original work of
James Roseborough and Ian Farmer is not lost.
Unfortunately, I was not able to contact either James or Ian to hand over
ownership of the Github organization/repo as I have originally intended to.
The community however seems interested enough to continue work on the original
sources and therefore I have decided to make sure that any useful pull requests
that may add some value to the original code base shall be merged in from now
on.<br>
-- Benjamin P. Jung, Jan. 26th 2018
</div>
<head> <h1>Getting Started with LuaJ</h1>
<title>Getting Started with LuaJ</title> James Roseborough, Ian Farmer, Version 3.0.2
<link rel="stylesheet" type="text/css" href="http://www.lua.org/lua.css">
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
</head>
<body>
<hr>
<h1>
<a href="README.html"><img src="http://sourceforge.net/dbimage.php?id=196139" alt="" border="0"></a>
Getting Started with LuaJ
</h1>
James Roseborough, Ian Farmer, Version 3.0.1
<p> <p>
<small> <small>
Copyright &copy; 2009-2014 Luaj.org. Copyright &copy; 2009-2014 Luaj.org.
Freely available under the terms of the Freely available under the terms of the
<a href="http://sourceforge.net/dbimage.php?id=196142">Luaj license</a>. <a href="LICENSE">Luaj license</a>.
</small> </small>
<hr> <hr>
<p> <p>
@@ -120,7 +123,7 @@ in comparison with the standard C distribution.
<td>16.794</td> <td>16.794</td>
<td>11.274</td> <td>11.274</td>
<td>Java</td> <td>Java</td>
<td>java -cp luaj-jse-3.0.1.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr> <td>java -cp luaj-jse-3.0.2.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
<tr valign="top"> <tr valign="top">
<td></td> <td></td>
<td></td> <td></td>
@@ -130,7 +133,7 @@ in comparison with the standard C distribution.
<td>36.894</td> <td>36.894</td>
<td>15.163</td> <td>15.163</td>
<td></td> <td></td>
<td>java -cp luaj-jse-3.0.1.jar lua -n fannkuch.lua 10</td></tr> <td>java -cp luaj-jse-3.0.2.jar lua -n fannkuch.lua 10</td></tr>
<tr valign="top"> <tr valign="top">
<td>lua</td> <td>lua</td>
<td>5.1.4</td> <td>5.1.4</td>
@@ -186,7 +189,7 @@ It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for a
From the main distribution directory line type: From the main distribution directory line type:
<pre> <pre>
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/hello.lua java -cp luaj-jse-3.0.2.jar lua examples/lua/hello.lua
</pre> </pre>
<p> <p>
@@ -198,7 +201,7 @@ You should see the following output:
To see how luaj can be used to acccess most Java API's including swing, try: To see how luaj can be used to acccess most Java API's including swing, try:
<pre> <pre>
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/swingapp.lua java -cp luaj-jse-3.0.2.jar lua examples/lua/swingapp.lua
</pre> </pre>
<p> <p>
@@ -213,8 +216,8 @@ Links to sources:<pre>
From the main distribution directory line type: From the main distribution directory line type:
<pre> <pre>
java -cp lib/luaj-jse-3.0.1.jar luac examples/lua/hello.lua java -cp luaj-jse-3.0.2.jar luac examples/lua/hello.lua
java -cp lib/luaj-jse-3.0.1.jar lua luac.out java -cp luaj-jse-3.0.2.jar lua luac.out
</pre> </pre>
<p> <p>
@@ -228,8 +231,8 @@ Luaj can compile lua sources or binaries directly to java bytecode if the bcel l
<pre> <pre>
ant bcel-lib ant bcel-lib
java -cp &quot;lib/luaj-jse-3.0.1.jar;lib/bcel-5.2.jar&quot; luajc -s examples/lua -d . hello.lua java -cp &quot;luaj-jse-3.0.2.jar;lib/bcel-5.2.jar&quot; luajc -s examples/lua -d . hello.lua
java -cp &quot;lib/luaj-jse-3.0.1.jar;.&quot; lua -l hello java -cp &quot;luaj-jse-3.0.2.jar;.&quot; lua -l hello
</pre> </pre>
<p> <p>
@@ -240,7 +243,7 @@ but the compiled classes must be in the class path at runtime, unless runtime ji
<p> <p>
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path: Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
<pre> <pre>
java -cp &quot;lib/luaj-jse-3.0.1.jar;lib/bcel-5.2.jar&quot; lua -b examples/lua/hello.lua java -cp &quot;luaj-jse-3.0.2.jar;lib/bcel-5.2.jar&quot; lua -b examples/lua/hello.lua
</pre> </pre>
@@ -251,7 +254,7 @@ A simple hello, world example in luaj is:
<pre> <pre>
import org.luaj.vm2.*; import org.luaj.vm2.*;
import org.luaj.vm2.lib.jse.*; import org.luaj.vm2.libs.jse.*;
Globals globals = JsePlatform.standardGlobals(); Globals globals = JsePlatform.standardGlobals();
LuaValue chunk = globals.load("print 'hello, world'"); LuaValue chunk = globals.load("print 'hello, world'");
@@ -284,7 +287,7 @@ A simple example may be found in
</pre> </pre>
<p> <p>
You must include the library <b>lib/luaj-jse-3.0.1.jar</b> in your class path. You must include the library <b>luaj-jse-3.0.2.jar</b> in your class path.
<h2>Run a script in a MIDlet</h2> <h2>Run a script in a MIDlet</h2>
@@ -293,7 +296,7 @@ For MIDlets the <em>JmePlatform</em> is used instead:
<pre> <pre>
import org.luaj.vm2.*; import org.luaj.vm2.*;
import org.luaj.vm2.lib.jme.*; import org.luaj.vm2.libs.jme.*;
Globals globals = JmePlatform.standardGlobals(); Globals globals = JmePlatform.standardGlobals();
LuaValue chunk = globals.loadfile("examples/lua/hello.lua"); LuaValue chunk = globals.loadfile("examples/lua/hello.lua");
@@ -311,13 +314,9 @@ A simple example may be found in
</pre> </pre>
<p> <p>
You must include the library <b>lib/luaj-jme-3.0.1.jar</b> in your midlet jar. You must include the library <b>luaj-jme-3.0.2.jar</b> in your midlet jar.
<p> <p>
An ant script to build and run the midlet is in
<pre>
<a href="build-midlet.xml">build-midlet.xml</a>
</pre>
<p> <p>
You must install the wireless toolkit and define <em>WTK_HOME</em> for this script to work. You must install the wireless toolkit and define <em>WTK_HOME</em> for this script to work.
@@ -341,7 +340,7 @@ You can also look up the engine by language "lua" or mimetypes "text/lua" or "ap
All standard aspects of script engines including compiled statements are supported. All standard aspects of script engines including compiled statements are supported.
<p> <p>
You must include the library <b>lib/luaj-jse-3.0.1.jar</b> in your class path. You must include the library <b>luaj-jse-3.0.2.jar</b> in your class path.
<p> <p>
A working example may be found in A working example may be found in
@@ -352,8 +351,8 @@ A working example may be found in
To compile and run it using Java 1.6 or higher: To compile and run it using Java 1.6 or higher:
<pre> <pre>
javac -cp lib/luaj-jse-3.0.1.jar examples/jse/ScriptEngineSample.java javac -cp luaj-jse-3.0.2.jar examples/jse/ScriptEngineSample.java
java -cp &quot;lib/luaj-jse-3.0.1.jar;examples/jse&quot; ScriptEngineSample java -cp &quot;luaj-jse-3.0.2.jar;examples/jse&quot; ScriptEngineSample
</pre> </pre>
<h2>Excluding the lua bytecode compiler</h2> <h2>Excluding the lua bytecode compiler</h2>
@@ -415,7 +414,7 @@ and the math operations include all those supported by Java SE.
Android applications should use the JsePlatform, and can include the <a href="#luajava">Luajava</a> library Android applications should use the JsePlatform, and can include the <a href="#luajava">Luajava</a> library
to simplify access to underlying Android APIs. to simplify access to underlying Android APIs.
A specialized Globals.finder should be provided to find scripts and data for loading. A specialized Globals.finder should be provided to find scripts and data for loading.
See <a href="examples/android/src/android/LuajView">examples/android/src/android/LuajView</a> See <a href="examples/android/src/android/LuajView.java">examples/android/src/android/LuajView.java</a>
for an example that loads from the "res" Android project directory. for an example that loads from the "res" Android project directory.
The ant build script is <a href="examples/android/build.xml">examples/android/build.xml</a>. The ant build script is <a href="examples/android/build.xml">examples/android/build.xml</a>.
@@ -425,7 +424,6 @@ Applets in browsers should use the JsePlatform. The permissions model in applet
highly restrictive, so a specialization of the <a href="#luajava">Luajava</a> library must be used that highly restrictive, so a specialization of the <a href="#luajava">Luajava</a> library must be used that
uses default class loading. This is illustrated in the sample Applet uses default class loading. This is illustrated in the sample Applet
<a href="examples/jse/SampleApplet.java">examples/jse/SampleApplet.java</a>, <a href="examples/jse/SampleApplet.java">examples/jse/SampleApplet.java</a>,
which can be built using <a href="build-applet.xml">build-applet.xml</a>.
<h3>JmePlatform</h3> <h3>JmePlatform</h3>
@@ -444,7 +442,6 @@ In particular Globals.finder is overridden to load as resources, so scripts shou
colocated with class files in the MIDlet jar file. <a href="#luajava">Luajava</a> cannot be used. colocated with class files in the MIDlet jar file. <a href="#luajava">Luajava</a> cannot be used.
Camples code is in Camples code is in
<a href="examples/jme/SampleMIDlet.java">examples/jme/SampleMIDlet.java</a>, <a href="examples/jme/SampleMIDlet.java">examples/jme/SampleMIDlet.java</a>,
which can be built using <a href="build-midlet.xml">build-midlet.xml</a>.
<h2>Thread Safety</h2> <h2>Thread Safety</h2>
@@ -569,7 +566,7 @@ create globals that contain the debug library in addition to the other standard
To install dynamically from lua use java-class-based require:</em>: To install dynamically from lua use java-class-based require:</em>:
<pre> <pre>
require 'org.luaj.vm2.lib.DebugLib' require 'org.luaj.vm2.libs.DebugLib'
</pre> </pre>
The <em>lua</em> command line utility includes the <em>debug</em> library by default. The <em>lua</em> command line utility includes the <em>debug</em> library by default.
@@ -593,7 +590,7 @@ The following lua script will open a swing frame on Java SE:
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading. See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
Or try running it using: Or try running it using:
<pre> <pre>
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/swingapp.lua java -cp luaj-jse-3.0.2.jar lua examples/lua/swingapp.lua
</pre> </pre>
<p> <p>
@@ -669,11 +666,11 @@ The simplest way to implement a function is to choose a base class based on the
LuaJ provides 5 base classes for this purpose, depending if the function has 0, 1, 2, 3 or variable arguments, LuaJ provides 5 base classes for this purpose, depending if the function has 0, 1, 2, 3 or variable arguments,
and if it provide multiple return values. and if it provide multiple return values.
<pre> <pre>
<a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/ZeroArgFunction.html">org.luaj.vm2.lib.ZeroArgFunction</a> <a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/ZeroArgFunction.html">org.luaj.vm2.libs.ZeroArgFunction</a>
<a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/OneArgFunction.html">org.luaj.vm2.lib.OneArgFunction</a> <a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/OneArgFunction.html">org.luaj.vm2.libs.OneArgFunction</a>
<a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/TwoArgFunction.html">org.luaj.vm2.lib.TwoArgFunction</a> <a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/TwoArgFunction.html">org.luaj.vm2.libs.TwoArgFunction</a>
<a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/ThreeArgFunction.html">org.luaj.vm2.lib.ThreeArgFunction</a> <a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/ThreeArgFunction.html">org.luaj.vm2.libs.ThreeArgFunction</a>
<a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/VarArgFunction.html">org.luaj.vm2.lib.VarArgFunction</a> <a href="http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/VarArgFunction.html">org.luaj.vm2.libs.VarArgFunction</a>
</pre> </pre>
Each of these functions has an abstract method that must be implemented, Each of these functions has an abstract method that must be implemented,
@@ -727,7 +724,7 @@ in the environment that can be called from lua.
A complete example of Java code for a simple toy library is in <a href="examples/jse/hyperbolic.java">examples/jse/hyperbolic.java</a> A complete example of Java code for a simple toy library is in <a href="examples/jse/hyperbolic.java">examples/jse/hyperbolic.java</a>
<pre> <pre>
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.*; import org.luaj.vm2.libs.*;
public class hyperbolic extends TwoArgFunction { public class hyperbolic extends TwoArgFunction {
@@ -842,7 +839,7 @@ For JSE projects, add this dependency for the luaj-jse jar:
&lt;dependency&gt; &lt;dependency&gt;
&lt;groupId&gt;org.luaj&lt;/groupId&gt; &lt;groupId&gt;org.luaj&lt;/groupId&gt;
&lt;artifactId&gt;luaj-jse&lt;/artifactId&gt; &lt;artifactId&gt;luaj-jse&lt;/artifactId&gt;
&lt;version&gt;3.0.1&lt;/version&gt; &lt;version&gt;3.0.2&lt;/version&gt;
&lt;/dependency&gt; &lt;/dependency&gt;
</pre> </pre>
while for JME projects, use the luaj-jme jar: while for JME projects, use the luaj-jme jar:
@@ -850,7 +847,7 @@ while for JME projects, use the luaj-jme jar:
&lt;dependency&gt; &lt;dependency&gt;
&lt;groupId&gt;org.luaj&lt;/groupId&gt; &lt;groupId&gt;org.luaj&lt;/groupId&gt;
&lt;artifactId&gt;luaj-jme&lt;/artifactId&gt; &lt;artifactId&gt;luaj-jme&lt;/artifactId&gt;
&lt;version&gt;3.0.1&lt;/version&gt; &lt;version&gt;3.0.2&lt;/version&gt;
&lt;/dependency&gt; &lt;/dependency&gt;
</pre> </pre>
@@ -880,16 +877,12 @@ Unit test scripts can be found in these locations
test/lua/*.lua test/lua/*.lua
test/lua/errors/*.lua test/lua/errors/*.lua
test/lua/perf/*.lua test/lua/perf/*.lua
test/lua/luaj3.0.1-tests.zip test/lua/luaj3.0.2-tests.zip
</pre> </pre>
<h2>Code coverage</h2> <h2>Code coverage</h2>
<p> <p>
A build script for running unit tests and producing code coverage statistics is in
<pre>
<a href="build-coverage.xml">build-coverage.xml</a>
</pre>
It relies on the cobertura code coverage library. It relies on the cobertura code coverage library.
@@ -930,7 +923,7 @@ Files are no longer hosted at LuaForge.
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a> <li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a>
and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0/</a></li> and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0/</a></li>
<li>Major refactor of luajava type coercion logic, improve method selection.</li> <li>Major refactor of luajava type coercion logic, improve method selection.</li>
<li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li> <li>Add luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
<tr valign="top"><td>&nbsp;&nbsp;<b>2.0.3</b></td><td><ul> <tr valign="top"><td>&nbsp;&nbsp;<b>2.0.3</b></td><td><ul>
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li> <li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
@@ -948,7 +941,6 @@ and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sour
<li>Add explicit Globals object to manage global state, especially to imrpove thread safety </li> <li>Add explicit Globals object to manage global state, especially to imrpove thread safety </li>
<li>Drop support for lua source to java surce (lua2java) in favor of direct java bytecode output (luajc) </li> <li>Drop support for lua source to java surce (lua2java) in favor of direct java bytecode output (luajc) </li>
<li>Remove compatibility functions like table.getn(), table.maxn(), table.foreach(), and math.log10() </li> <li>Remove compatibility functions like table.getn(), table.maxn(), table.foreach(), and math.log10() </li>
<li>Add ability to create runnable jar file from lua script with sample build file build-app.xml </li>
<li>Supply environment as second argument to LibFunction when loading via require() </li> <li>Supply environment as second argument to LibFunction when loading via require() </li>
<li>Fix bug 3597515 memory leak due to string caching by simplifying caching logic.</li> <li>Fix bug 3597515 memory leak due to string caching by simplifying caching logic.</li>
<li>Fix bug 3565008 so that short substrings are backed by short arrays.</li> <li>Fix bug 3565008 so that short substrings are backed by short arrays.</li>
@@ -1017,6 +1009,11 @@ and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sour
<li>Move online docs to <a href="http://luaj.org/luaj/3.0/api/index.html">http://luaj.org/luaj/3.0/api/</a></li> <li>Move online docs to <a href="http://luaj.org/luaj/3.0/api/index.html">http://luaj.org/luaj/3.0/api/</a></li>
<li>Fix os.time() conversions for pm times.</li> <li>Fix os.time() conversions for pm times.</li>
<tr valign="top"><td>&nbsp;&nbsp;<b>3.0.2</b></td><td><ul>
<li>Fix JsePlatform.luaMain() to provide an "arg" table in the chunk's environment.</li>
<li>Let JsePlatform.luaMain() return values returned by the main chunk.</li>
<li>Add synchronization to CoerceJavaToLua.COERCIONS map.</li>
</ul></td></tr> </ul></td></tr>
</table></td></tr></table> </table></td></tr></table>
@@ -1026,7 +1023,10 @@ and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sour
<li>debug code may not be completely removed by some obfuscators <li>debug code may not be completely removed by some obfuscators
<li>tail calls are not tracked in debug information <li>tail calls are not tracked in debug information
<li>mixing different versions of luaj in the same java vm is not supported <li>mixing different versions of luaj in the same java vm is not supported
<li>LuaJ runs on the host VM garbage collector, so object lifetime, weak reference timing, and finalization behavior are not identical to native Lua
<li>the <code>__gc</code> metamethod is not supported as a reliable Lua finalization mechanism
<li>values associated with weak keys may linger longer than expected <li>values associated with weak keys may linger longer than expected
<li>cascading weak-table collection can require multiple host GC cycles
<li>behavior of luaj when a SecurityManager is used has not been fully characterized <li>behavior of luaj when a SecurityManager is used has not been fully characterized
<li>negative zero is treated as identical to integer value zero throughout luaj <li>negative zero is treated as identical to integer value zero throughout luaj
<li>lua compiled into java bytecode using luajc cannot use string.dump() or xpcall() <li>lua compiled into java bytecode using luajc cannot use string.dump() or xpcall()
@@ -1034,6 +1034,22 @@ and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sour
<li>shared metatables for string, bool, etc are shared across Globals instances in the same class loader <li>shared metatables for string, bool, etc are shared across Globals instances in the same class loader
<li>orphaned threads will not be collected unless garbage collection is run and sufficient time elapses <li>orphaned threads will not be collected unless garbage collection is run and sufficient time elapses
</ul> </ul>
<h3>Garbage Collection And Resources</h3>
LuaJ does not implement the same garbage collector semantics as native Lua. Garbage collection is delegated to the host JVM or CLDC runtime, so <code>collectgarbage()</code> is only a hint and should not be used as a resource-management primitive.
<p>
In particular:
<ul>
<li>Do not rely on garbage collection to close files, sockets, database handles, or other resources.
<li>Always call <code>close()</code> explicitly on files and iterators that own files.
<li><code>io.lines(filename)</code> opens a file implicitly. If iteration is abandoned early, that file may remain open until explicitly collected by the host runtime.
<li>Prefer <code>local f = assert(io.open(...))</code> together with <code>f:lines()</code> and an explicit <code>f:close()</code> when deterministic cleanup matters.
<li>For implicit line iterators that need deterministic early cleanup, use <code>io.linesx(filename)</code> and call <code>iterator:close()</code>.
<li><code>file:linesx()</code> provides the same closable iterator API for already-open files.
<li>On Windows, leaked file handles can prevent rename or delete operations until the process exits.
<li>On JME/CLDC, finalization support may be absent, so explicit close is mandatory.
</ul>
<p>
Short-lived locals may also remain reachable longer than expected because host stack/register reuse is implementation-dependent. If prompt reclamation matters, isolate temporary allocations in functions and clear large references explicitly instead of assuming block exit is enough.
<h3>File Character Encoding</h3> <h3>File Character Encoding</h3>
Source files can be considered encoded in UTF-8 or ISO-8859-1 and results should be as expected, Source files can be considered encoded in UTF-8 or ISO-8859-1 and results should be as expected,
with literal string contianing quoted characters compiling to the same byte sequences as the input. with literal string contianing quoted characters compiling to the same byte sequences as the input.

View File

@@ -1,108 +0,0 @@
<!-- And build script to compile lua scripts into runnable jar files using the "luajc"
lua to java bytecode compiler.
Each source file is converted into a runnable jar file that takes arguments from the command line.
For example, the program test/lua/perf/binarytrees.lua is converted to a jar that can be run with
java -jar binarytrees.jar 15
-->
<project default="all">
<import file="build.xml"/>
<import file="build-libs.xml"/>
<available file="luaj-jse-${version}.jar" property="luaj.lib.exists"/>
<!-- this may need to be changed when building on mac -->
<property name="rt.jar" value="${java.home}/lib/rt.jar"/>
<target name="luaj-lib" unless="luaj.lib.exists">
<antcall target="jar-jse"/>
</target>
<macrodef name="perftest">
<attribute name="cmd"/>
<sequential>
<echo level="info">------ @{cmd}</echo>
<exec executable="bash">
<arg value="-c"/>
<arg value="time @{cmd}"/>
</exec>
</sequential>
</macrodef>
<macrodef name="buildappjar">
<attribute name="luaprog"/>
<attribute name="arg" default=""/>
<attribute name="srcdir" default="test/lua/perf"/>
<sequential>
<echo level="info">=========== @{srcdir}/@{luaprog} =============</echo>
<delete dir="build/@{luaprog}"/>
<mkdir dir="build/@{luaprog}/class"/>
<java classname="luajc">
<classpath>
<pathelement path="luaj-jse-${version}.jar"/>
<pathelement path="lib/bcel-5.2.jar"/>
</classpath>
<arg value="-s"/>
<arg path="@{srcdir}"/>
<arg value="-d"/>
<arg path="build/@{luaprog}/class"/>
<arg value="-m"/>
<arg value="-v"/>
<arg value="@{luaprog}.lua"/>
</java>
<jar destfile="build/@{luaprog}.jar">
<fileset dir="build/@{luaprog}/class"/>
<zipfileset includes="org/luaj/vm2/*.class,org/luaj/vm2/lib/*.class,org/luaj/vm2/lib/jse/*.class,org/luaj/vm2/compiler/*.class" src="luaj-jse-${version}.jar" />
<manifest>
<attribute name="Main-Class" value="@{luaprog}" />
</manifest>
</jar>
<unjar src="build/@{luaprog}.jar" dest="build/@{luaprog}/unjarred"/>
<perftest cmd="java -jar build/@{luaprog}.jar @{arg}"/>
<!-- The following can be adapted to produce an optimized jar.
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
<proguard>
-injars build/@{luaprog}.jar
-outjars build/@{luaprog}-opt.jar
-libraryjars ${rt.jar}
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
-printmapping build/@{luaprog}.map
-keep public class @{luaprog} {
public static void main(java.lang.String[]);
}
</proguard>
<unjar src="build/@{luaprog}-opt.jar" dest="build/@{luaprog}/unjarred-opt"/>
<perftest cmd="java -jar build/@{luaprog}-opt.jar @{arg}"/>
-->
</sequential>
</macrodef>
<target name="binarytrees" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="binarytrees" arg="15"/>
</target>
<target name="fannkuch" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="fannkuch" arg="10"/>
</target>
<target name="nbody" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="nbody" arg="1000000"/>
</target>
<target name="nsieve" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="nsieve" arg="8"/>
</target>
<target name="swingapp" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="swingapp" srcdir="examples/lua"/>
</target>
<target name="allappjars" depends="binarytrees,fannkuch,nbody,nsieve,swingapp"/>
<target name="all" depends="allappjars"/>
</project>

View File

@@ -1,116 +0,0 @@
<?xml version="1.0"?>
<project name="sample" default="main" basedir=".">
<property file="version.properties"/>
<!-- find libs -->
<import file="build-libs.xml"/>
<!-- main java class -->
<property name="java.dir" value="examples/jse"/>
<property name="java.name" value="SampleApplet"/>
<!-- main script -->
<property name="script.dir" value="examples/lua"/>
<property name="script.name" value="swingapplet"/>
<property name="image.name" value="logo.gif"/>
<!-- location of luaj jar -->
<property name="libs.dir" value="lib"/>
<property name="luaj.jar" value="${libs.dir}/luaj-jse-${version}.jar"/>
<!-- location of build results -->
<property name="build.dir" value="build/applet"/>
<target name="clean">
<delete failonerror="false" dir="${build.dir}"/>
</target>
<target name="dirs">
<mkdir dir="build/applet/classes"/>
</target>
<target name="classes" depends="dirs">
<copy todir="${build.dir}">
<fileset dir="${script.dir}" includes="${script.name}.lua,${image.name}"/>
</copy>
<javac destdir="${build.dir}/classes" source="1.4" target="1.4"
classpath="${luaj.jar}" srcdir="${java.dir}" includes="${java.name}.java"/>
</target>
<target name="manifest" depends="dirs">
<manifest file="${build.dir}/MANIFEST.MF">
<attribute name="Permissions" value="sandbox"/>
<attribute name="Main-class" value="${java.name}"/>
</manifest>
</target>
<target name="jar" depends="classes,manifest">
<jar destfile="${build.dir}/${script.name}.jar"
manifest="${build.dir}/MANIFEST.MF">
<fileset dir="${build.dir}" includes="*.lua"/>
<fileset dir="${build.dir}/classes"/>
<zipfileset
src="${luaj.jar}"
excludes="**/script/*,**/luajc/**,**/parser/**,**/ast/**,lua*"/>
</jar>
</target>
<target name="obf" depends="jar,proguard-lib">
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
<copy file="${build.dir}/${script.name}.jar"
tofile="${build.dir}/${script.name}-unobfuscated.jar"/>
<proguard>
-injars ${build.dir}/${script.name}-unobfuscated.jar
-outjars ${build.dir}/${script.name}.jar
-libraryjars ${java.home}/lib/rt.jar
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
-printmapping ${build.dir}/mapping.txt
-keep public class * extends java.applet.Applet
-target 1.4
</proguard>
</target>
<target name="sign" depends="obf">
<signjar jar="${build.dir}/${script.name}.jar"
alias="${sign.alias}"
storepass="${sign.storepass}"
keypass="${sign.keypass}"
keystore="${sign.keystore}" />
</target>
<target name="html" depends="dirs">
<echoxml file="build/applet/LuajSampleApplet.html">
<html>
<head><title>Luaj Sample Applet</title></head>
<body>
<h1>Luaj Sample Applet</h1>
Requires browser that supports applets.
${script.name}
<applet archive='${script.name}.jar'
code='${java.name}.class'
width='800'
height='640' >
<param name='luaj.script' value='${script.name}.lua'/>
<param name="java_version" value="1.4+"/>
</applet>
</body>
</html>
</echoxml>
</target>
<target name="run" depends="jar,html">
<exec executable="open" spawn="true">
<arg value="-a Firefox"/>
<arg path="build/applet/LuajSampleApplet.html"/>
</exec>
</target>
<target name="all" depends="clean,sign,html,run"/>
<target name="main" depends="sign,html"/>
</project>

View File

@@ -1,119 +0,0 @@
<project default="all" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<!--
Run code coverage for unit tests on the luaj vm and libraries.
-->
<property name="classes.dir" value="build/classes-debug" />
<property name="instrumented.dir" value="build/instrumented" />
<property name="reports.xml.dir" value="build/reports-junit-xml" />
<property name="reports.html.dir" value="build/reports-junit-html" />
<property name="coverage.xml.dir" value="build/reports-coverage-xml" />
<property name="coverage.html.dir" value="build/reports-coverage-html" />
<property name="cobertura.serfile" value="cobertura.ser" />
<property name="cobertura.logfile" value="cobertura.log" />
<artifact:dependencies filesetId="cobutura.fileset">
<dependency groupId="net.sourceforge.cobertura" artifactId="cobertura" version="1.9.4.1"/>
<dependency groupId="junit" artifactId="junit" version="3.8.1"/>
</artifact:dependencies>
<path id="cobertura.classpath">
<fileset refid="cobutura.fileset" />
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
<import file="wtk.xml"/>
<property environment="env"/>
<target name="clean" description="Remove all files created by the build/test process.">
<delete dir="${classes.dir}" failonerror="yes"/>
<delete dir="${instrumented.dir}" failonerror="yes"/>
<delete file="${cobertura.logfile}" />
<delete file="${cobertura.serfile}" />
</target>
<target name="init">
<ant antfile="build.xml" target="bcel-lib"/>
<ant antfile="build.xml" target="luaj1-lib"/>
<mkdir dir="${classes.dir}" />
<mkdir dir="${instrumented.dir}" />
<mkdir dir="${reports.xml.dir}" />
<mkdir dir="${reports.html.dir}" />
<mkdir dir="${coverage.xml.dir}" />
<mkdir dir="${coverage.html.dir}" />
</target>
<target name="compile" depends="init,wtk-or-fail">
<javac destdir="${classes.dir}" debug="yes" target="1.5">
<classpath refid="cobertura.classpath" />
<classpath refid="wtk-libs" />
<classpath path="lib/bcel-5.2.jar" />
<src path="src/core"/>
<src path="src/jme"/>
<src path="src/jse"/>
<src path="test/junit"/>
</javac>
</target>
<target name="instrument" depends="compile">
<delete file="${cobertura.serfile}"/>
<delete dir="${instrumented.dir}" failonerror="no"/>
<cobertura-instrument datafile="${cobertura.serfile}" todir="${instrumented.dir}">
<fileset dir="${classes.dir}">
<include name="org/luaj/vm2/*.class" />
<include name="org/luaj/vm2/lib/*.class" />
<include name="org/luaj/vm2/lib/jse/*.class" />
<include name="org/luaj/vm2/lib/jme/*.class" />
<include name="org/luaj/vm2/compiler/*.class" />
<include name="org/luaj/vm2/luajc/*.class" />
<include name="org/luaj/vm2/lua2java/*.class" />
<include name="org/luaj/vm2/parser/*.class" />
<include name="org/luaj/vm2/ast/*.class" />
<exclude name="**/*Test*.class" />
</fileset>
</cobertura-instrument>
</target>
<target name="test">
<junit fork="yes" dir="${basedir}" showoutput="yes">
<sysproperty key="net.sourceforge.cobertura.serfile"
file="${basedir}/${cobertura.serfile}" />
<classpath location="${instrumented.dir}" />
<classpath location="${classes.dir}" />
<classpath refid="cobertura.classpath" />
<classpath location="test/lua" />
<classpath location="test/junit/org/luaj/vm2/compiler" />
<classpath location="test/junit/org/luaj/vm2/vm1" />
<classpath path="lib/bcel-5.2.jar" />
<formatter type="xml" />
<batchtest todir="${reports.xml.dir}">
<fileset dir="test/junit">
<include name="org/luaj/vm2/AllTests.java" />
</fileset>
</batchtest>
</junit>
<junitreport todir="${reports.xml.dir}">
<fileset dir="${reports.xml.dir}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${reports.html.dir}" />
</junitreport>
</target>
<target name="report">
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.xml.dir}" format="xml" />
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.html.dir}">
<fileset dir="src/core"/>
<fileset dir="src/jse"/>
<fileset dir="src/jme"/>
</cobertura-report>
</target>
<target name="coverage" depends="clean,init,compile,instrument,test,report"/>
<target name="all" depends="coverage" />
</project>

View File

@@ -1,56 +0,0 @@
<project default="all-libs">
<available file="lib/midpapi20.jar" property="midpapi.lib.exists"/>
<available file="lib/bcel-5.2.jar" property="bcel.lib.exists"/>
<available file="lib/javacc.jar" property="javacc.lib.exists"/>
<available file="lib/proguard.jar" property="proguard.lib.exists"/>
<available file="lib/antenna-bin-1.2.0-beta.jar" property="antenna.lib.exists"/>
<available file="lib/junit.jar" property="junit.lib.exists"/>
<available file="lib/cobertura.jar" property="cobertura.lib.exists"/>
<available file="lib/microemulator.jar" property="microemulator.lib.exists"/>
<macrodef name="download">
<attribute name="zipname"/>
<attribute name="jars" default="**/*.jar"/>
<sequential>
<mkdir dir="lib"/>
<get src="http://luaj.sourceforge.net/lib/@{zipname}.tar.gz"
dest="lib/@{zipname}.tar.gz"/>
<gunzip src="lib/@{zipname}.tar.gz" dest="lib/@{zipname}.tar"/>
<untar src="lib/@{zipname}.tar" dest="lib" overwrite="true">
<patternset>
<include name="@{jars}"/>
</patternset>
<mapper type="flatten"/>
</untar>
</sequential>
</macrodef>
<target name="wtk-libs" unless="midpapi.lib.exists">
<download zipname="wtk-2.5.2-api"/>
</target>
<target name="bcel-lib" unless="bcel.lib.exists">
<download zipname="/bcel-5.2"/>
</target>
<target name="javacc-lib" unless="javacc.lib.exists">
<download zipname="javacc-5.0"/>
</target>
<target name="proguard-lib" unless="proguard.lib.exists">
<download zipname="proguard4.6"/>
</target>
<target name="antenna-lib" unless="antenna.lib.exists">
<download zipname="antenna-bin-1.2.0-beta"/>
</target>
<target name="junit-lib" unless="junit.lib.exists">
<download zipname="junit-3.8.2"/>
</target>
<target name="cobertura-lib" unless="cobertura.lib.exists">
<download zipname="cobertura-1.9.4.1-bin"/>
</target>
<target name="microemulator-lib" unless="microemulator.lib.exists">
<download zipname="microemulator-2.0.4" jars="**/microemulator.jar"/>
</target>
<target name="all-libs" depends="wtk-libs,bcel-lib,javacc-lib,proguard-lib,antenna-lib,junit-lib,cobertura-lib"/>
</project>

View File

@@ -1,176 +0,0 @@
<project default="usage">
<!-- Ant file to deploy to maven once the distribution is released on sourceforge.
-->
<property file="version.properties"/>
<macrodef name="write_pom">
<attribute name="platform"/>
<attribute name="snapshot" default=""/>
<sequential>
<mkdir dir="build/maven-${version}"/>
<echo file="build/maven-${version}/luaj-@{platform}-${version}@{snapshot}.pom"><![CDATA[<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.luaj</groupId>
<artifactId>luaj-]]>@{platform}<![CDATA[</artifactId>
<version>]]>${version}@{snapshot}<![CDATA[</version>
<packaging>jar</packaging>
<name>luaj-]]>@{platform}<![CDATA[</name>
<description>Luaj ]]>${version}<![CDATA[ for the ]]>@{platform}<![CDATA[ platform</description>
<url>http://sourceforge.net/projects/luaj/</url>
<licenses>
<license>
<name>MIT License</name>
<url>http://luaj.sourceforge.net/license.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>jrosebor</id>
<name>James Roseborough</name>
<email>jim.roseborough@luaj.org</email>
<timezone>-8</timezone>
<roles></roles>
</developer>
<developer>
<id>ifarmer</id>
<name>Ian Farmer</name>
<email>ian.farmer@luaj.org</email>
<timezone>-8</timezone>
<roles></roles>
</developer>
</developers>
<scm>
<url>http://luaj.cvs.sourceforge.net/viewvc/luaj/luaj-vm/</url>
</scm>
</project>
]]></echo>
</sequential>
</macrodef>
<macrodef name="prepare_files">
<attribute name="platform"/>
<attribute name="snapshot" default=""/>
<sequential>
<mkdir dir="build/maven-${version}"/>
<write_pom platform="@{platform}" snapshot="@{snapshot}"/>
<copy file="luaj-${version}.zip" todir="build/maven-${version}"/>
<unzip src="build/maven-${version}/luaj-${version}.zip" dest="build/maven-${version}"/>
<copy file="build/maven-${version}/luaj-${version}/lib/luaj-@{platform}-${version}.jar" todir="build/maven-${version}"/>
<!-- make a -sources file -->
<mkdir dir="build/maven-${version}/sources-@{platform}"/>
<copy todir="build/maven-${version}/sources-@{platform}">
<fileset dir="build/maven-${version}/luaj-${version}/src/core"/>
<fileset dir="build/maven-${version}/luaj-${version}/src/@{platform}"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-@{platform} ${version}"'/></tokenfilter>
</filterchain>
</copy>
<zip destfile="build/maven-${version}/luaj-@{platform}-${version}-sources.jar"
basedir="build/maven-${version}/sources-@{platform}"/>
<!-- make a -javadoc file -->
<mkdir dir="build/maven-${version}/javadoc-@{platform}"/>
<javadoc defaultexcludes="yes"
destdir="build/maven-${version}/javadoc-@{platform}"
author="true"
version="true"
use="true"
windowtitle="Luaj API">
<fileset dir="build/maven-${version}/sources-@{platform}">
<include name="org/luaj/vm/*.java"/>
<include name="org/luaj/vm2/*.java"/>
<include name="org/luaj/vm2/server/*.java"/>
<include name="**/LuaC.java"/>
<include name="**/LuaJC.java"/>
<include name="**/lib/*/*.java"/>
</fileset>
<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright &#169; 2007-2015 Luaj.org. All Rights Reserved.</i>]]></bottom>
<tag name="todo" scope="all" description="To do:"/>
<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
<link href="http://sourceforge.net/projects/luaj/"/>
</javadoc>
<zip destfile="build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"
basedir="build/maven-${version}/javadoc-@{platform}"/>
</sequential>
</macrodef>
<macrodef name="shapshot_files">
<attribute name="platform"/>
<sequential>
<exec executable="mvn">
<arg value="deploy:deploy-file"/>
<arg value="-Durl=https://oss.sonatype.org/content/repositories/snapshots"/>
<arg value="-DrepositoryId=nexus-releases"/>
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}-SNAPSHOT.pom"/>
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
<arg value="-Dsources=build/maven-${version}/luaj-@{platform}-${version}-sources.jar"/>
<arg value="-Djavadoc=build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"/>
</exec>
</sequential>
</macrodef>
<macrodef name="sign_and_deploy">
<attribute name="platform"/>
<sequential>
<exec executable="mvn">
<arg value="gpg:sign-and-deploy-file"/>
<arg value="-Durl=http://oss.sonatype.org/service/local/staging/deploy/maven2"/>
<arg value="-DrepositoryId=nexus-releases"/>
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}.pom"/>
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
<arg value="-Dsources=build/maven-${version}/luaj-@{platform}-${version}-sources.jar"/>
<arg value="-Djavadoc=build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"/>
</exec>
</sequential>
</macrodef>
<macrodef name="prepare_and_install">
<attribute name="platform"/>
<sequential>
<prepare_files platform="@{platform}"/>
<exec executable="mvn">
<arg value="install:install-file"/>
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}.pom"/>
</exec>
</sequential>
</macrodef>
<macrodef name="prepare_and_snapshot">
<attribute name="platform"/>
<sequential>
<prepare_files platform="@{platform}" snapshot="-SNAPSHOT"/>
<shapshot_files platform="@{platform}"/>
</sequential>
</macrodef>
<macrodef name="prepare_and_deploy">
<attribute name="platform"/>
<sequential>
<prepare_files platform="@{platform}"/>
<sign_and_deploy platform="@{platform}"/>
</sequential>
</macrodef>
<target name="install">
<prepare_and_install platform="jse"/>
<prepare_and_install platform="jme"/>
</target>
<target name="snapshot">
<prepare_and_snapshot platform="jse"/>
<prepare_and_snapshot platform="jme"/>
</target>
<target name="deploy">
<prepare_and_deploy platform="jse"/>
<prepare_and_deploy platform="jme"/>
</target>
<target name="usage">
<echo level="info">Usage: ant [-Dversion=${version}] -f build-maven.xml [install | shapshot | deploy]</echo>
</target>
</project>

View File

@@ -1,113 +0,0 @@
<?xml version="1.0"?>
<project name="sample" default="all" basedir=".">
<property file="version.properties"/>
<!-- find libs -->
<import file="build-libs.xml"/>
<!-- main script -->
<property name="script.name" value="hello"/>
<property name="script.dir" value="examples/lua"/>
<target name="clean">
<delete failonerror="false" dir="build"/>
</target>
<target name="dirs">
<mkdir dir="build"/>
<mkdir dir="build/tool"/>
<mkdir dir="build/classes"/>
</target>
<target name="tools" depends="dirs,bcel-lib,wtk-libs,microemulator-lib">
<javac destdir="build/tool" classpath="lib/bcel-5.2.jar">
<src path="src/core"/>
<src path="src/jse"/>
</javac>
</target>
<!-- compile script into lua bytecode -->
<target name="luac" depends="tools">
<java classname="luac" classpath="build/tool">
<arg line="-o build/classes/${script.name}.lua"/>
<arg line="${script.dir}/${script.name}.lua"/>
</java>
</target>
<!-- compile script into java bytecode -->
<target name="luajc" depends="tools,wtk-libs">
<java classname="luajc" classpath="build/tool:lib/bcel-5.2.jar">
<arg line="-verbose"/>
<arg line="-srcdir ${script.dir}"/>
<arg line="-destdir build/classes"/>
<arg line="${script.name}.lua"/>
</java>
</target>
<target name="classes" depends="dirs,wtk-libs">
<mkdir dir="build/midlet/src"/>
<copy todir="build/midlet/src">
<fileset dir="src/core"/>
<fileset dir="src/jme"/>
<fileset dir="examples/jme"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
</filterchain>
</copy>
<path id="wtk-libs">
<pathelement path="lib/cldcapi11.jar"/>
<pathelement path="lib/midpapi20.jar"/>
<pathelement path="lib/mmapi.jar"/>
</path>
<javac destdir="build/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
srcdir="build/midlet/src"/>
</target>
<target name="jar" depends="luajc,classes">
<jar destfile="build/sample-plain.jar"
basedir="build/classes"/>
</target>
<target name="obf" depends="jar,proguard-lib">
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
<proguard>
-injars build/sample-plain.jar
-outjars build/sample.jar
-libraryjars lib/midpapi20.jar
-libraryjars lib/cldcapi11.jar
-overloadaggressively
-repackageclasses ''
-microedition
-keep public class SampleMIDlet
-keep public class * extends org.luaj.vm2.LuaValue
</proguard>
</target>
<target name="jad" depends="obf">
<length file="build/sample.jar" property="sample.jar.length" />
<echo level="info">Jar file length is ${sample.jar.length}</echo>
<manifest file="build/sample.jad">
<attribute name="Built-By" value="luaj-${version}"/>
<attribute name="MIDlet-Name" value="Luaj ${script.name}"/>
<attribute name="MIDlet-Version" value="${version}"/>
<attribute name="MIDlet-Vendor" value="luaj.org"/>
<attribute name="MIDlet-Description" value="Luaj Sample Midlet"/>
<attribute name="MIDlet-1" value="${script.name}-${version}, , SampleMIDlet"/>
<attribute name="MIDlet-Jar-URL" value="sample.jar"/>
<attribute name="MIDlet-Jar-Size" value="${sample.jar.length}"/>
<attribute name="script" value="${script.name}"/>
</manifest>
</target>
<target name="package" depends="jad,jar,obf"/>
<target name="run" depends="jad,jar,obf,microemulator-lib">
<java jar="lib/microemulator.jar" fork="true">
<arg path="build/sample.jad"/>
</java>
</target>
<target name="all" depends="clean,package,run"/>
</project>

View File

@@ -1,68 +0,0 @@
<project default="all">
<import file="build.xml"/>
<property name="lua.command" value="lua"/>
<available file="luaj-jse-${version}.jar" property="luaj.lib.exists"/>
<available file="lib/jill-1.0.1.jar" property="jill.lib.exists"/>
<available file="lib/kahlua.jar" property="kahlua.lib.exists"/>
<available file="lib/mochalua-1.0.jar" property="mochalua.lib.exists"/>
<target name="luaj-lib" unless="luaj.lib.exists">
<antcall target="jar-jse"/>
</target>
<target name="jill-lib" unless="jill.lib.exists">
<mkdir dir="lib"/>
<get src="http://jillcode.googlecode.com/files/jill-1.0.1.zip"
dest="lib/jill-1.0.1.zip"/>
<unzip src="lib/jill-1.0.1.zip" dest="lib" overwrite="true"/>
<ant dir="lib/jill-1.0.1" target="compile"/>
<jar destfile="lib/jill-1.0.1.jar" basedir="lib/jill-1.0.1/compiled"/>
</target>
<target name="kahlua-lib" unless="kahlua.lib.exists">
<get src="http://kahlua.googlecode.com/files/kahlua.jar"
dest="lib/kahlua.jar"/>
</target>
<target name="mochalua-lib" unless="mochalua.lib.exists">
<get src="http://mochalua.googlecode.com/files/Mochalua%201.0.jar"
dest="lib/mochalua-1.0.jar"/>
</target>
<target name="perf-libs" depends="luaj-lib,bcel-lib,jill-lib,kahlua-lib,mochalua-lib"/>
<macrodef name="perftest">
<attribute name="program" default="lua"/>
<attribute name="luaprog" default="fannkuch.lua 10"/>
<attribute name="basedir" default="test/lua/perf/"/>
<sequential>
<echo level="info">------ @{program} @{luaprog}</echo>
<exec executable="bash">
<arg value="-c"/>
<arg value="time @{program} @{basedir}@{luaprog}"/>
</exec>
</sequential>
</macrodef>
<macrodef name="testcase">
<attribute name="luaprog" default="fannkuch.lua 10"/>
<sequential>
<echo level="info">=========== @{luaprog} =============</echo>
<perftest program="java -version" luaprog="" basedir=""/>
<perftest program="${lua.command}" luaprog="@{luaprog}"/>
<perftest program="java -cp luaj-jse-${version}.jar lua -n" luaprog="@{luaprog}"/>
<perftest program="java -cp luaj-jse-${version}.jar${path.separator}lib/bcel-5.2.jar lua -b" luaprog="@{luaprog}"/>
</sequential>
</macrodef>
<target name="alltests">
<testcase luaprog="binarytrees.lua 15"/>
<testcase luaprog="fannkuch.lua 10"/>
<testcase luaprog="nbody.lua 1000000"/>
<testcase luaprog="nsieve.lua 9"/>
</target>
<target name="all" depends="alltests"/>
</project>

208
build.xml
View File

@@ -1,208 +0,0 @@
<project default="all">
<property file="version.properties"/>
<property name="jar.name.jme" value="luaj-jme-${version}.jar"/>
<property name="jar.name.jse" value="luaj-jse-${version}.jar"/>
<property name="jar.name.sources" value="luaj-sources-${version}.jar"/>
<target name="clean-build">
<delete dir="build"/>
</target>
<target name="clean" depends="clean-build">
<delete>
<fileset dir="." includes="luaj-*.jar"/>
</delete>
<delete dir="examples/android/bin"/>
<delete dir="examples/android/build"/>
<delete dir="examples/android/gen"/>
<delete dir="examples/android/libs"/>
<delete dir="examples/maven/target"/>
</target>
<import file="build-libs.xml"/>
<target name="parser" depends="javacc-lib">
<java classname="javacc" classpath="lib/javacc.jar">
<arg line="grammar/LuaParser.jj"/>
</java>
</target>
<target name="plain-parser" depends="javacc-lib">
<java dir="src/jse" fork="true" classname="javacc" classpath="lib/javacc.jar">
<arg line="../../grammar/Lua52.jj"/>
</java>
</target>
<target name="compile" depends="wtk-libs,bcel-lib">
<delete dir="build/jme/src"/>
<delete dir="build/jse/src"/>
<mkdir dir="build/jme/src"/>
<mkdir dir="build/jse/src"/>
<mkdir dir="build/jme/classes"/>
<mkdir dir="build/jse/classes"/>
<copy todir="build/jme/src">
<fileset dir="src/core"/>
<fileset dir="src/jme"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
</filterchain>
</copy>
<copy todir="build/jse/src">
<fileset dir="src/core"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jse ${version}"'/></tokenfilter>
</filterchain>
</copy>
<copy todir="build/jse/src">
<fileset dir="src/jse"/>
<filterchain>
<tokenfilter><replacestring from='&lt;String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Stat&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Exp&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Name&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Block&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;TableField&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;VarExp&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Exp.VarExp&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Object,String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Double,String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Integer,Integer&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Integer,LocalVariableGen&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Exp,Integer&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;String,byte[]&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;String,Variable&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;LuaValue,String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;LuaString,String&gt;' to=''/></tokenfilter>
</filterchain>
</copy>
<path id="wtk-libs">
<pathelement path="lib/cldcapi11.jar"/>
<pathelement path="lib/midpapi20.jar"/>
<pathelement path="lib/mmapi.jar"/>
</path>
<javac destdir="build/jme/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
srcdir="build/jme/src"/>
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
classpath="lib/bcel-5.2.jar"
srcdir="build/jse/src"
excludes="**/script/*,**/Lua2Java*,**/server/*,lua*"/>
<javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
classpath="build/jse/classes"
srcdir="build/jse/src"
includes="**/script/*,**/Lua2Java*,**/server/*"/>
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
classpath="build/jse/classes"
srcdir="build/jse/src"
includes="lua*"/>
</target>
<target name="jar-jme" depends="compile">
<jar destfile="${jar.name.jme}" basedir="build/jme/classes"/>
</target>
<target name="jar-jse" depends="compile">
<jar destfile="${jar.name.jse}">
<fileset dir="build/jse/classes"/>
<fileset dir="src/jse/">
<include name="META-INF/services/**"/>
</fileset>
</jar>
</target>
<target name="jar-jse-sources" depends="compile">
<jar destfile="${jar.name.sources}">
<fileset dir="build/jme/src"/>
<fileset dir="build/jse/src"/>
</jar>
</target>
<target name="doc">
<delete dir="docs/api"/>
<mkdir dir="docs/api"/>
<javadoc defaultexcludes="yes"
destdir="docs/api"
author="true"
version="true"
use="true"
windowtitle="Luaj API">
<fileset dir="src/core" defaultexcludes="yes" includes="org/luaj/vm2/*.java,org/luaj/vm2/compiler/LuaC.java,org/luaj/vm2/lib/*.java"/>
<fileset dir="src/jse" defaultexcludes="yes" includes="org/luaj/vm2/lib/jse/*.java,org/luaj/vm2/luajc/LuaJC.java,org/luaj/vm2/server/*.java"/>
<fileset dir="src/jme" defaultexcludes="yes" includes="org/luaj/vm2/lib/jme/*.java"/>
<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright &#169; 2007-2015 Luaj.org. All Rights Reserved.</i>]]></bottom>
<tag name="todo" scope="all" description="To do:"/>
<group title="Core VM" packages="org.luaj.vm.*"/>
<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
<link href="http://sourceforge.net/projects/luaj/"/>
</javadoc>
</target>
<target name="dist" depends="all,doc">
<delete dir="build/luaj-${version}"/>
<mkdir dir="build/luaj-${version}/src"/>
<mkdir dir="build/luaj-${version}/lib"/>
<copy todir="build/luaj-${version}/src">
<fileset dir="src">
<exclude name="src/test/**"/>
<exclude name="**/antlr/**"/>
<exclude name="**/lst/**"/>
<exclude name="**/JavaCodeGenerator.java"/>
<exclude name="**/LuaJCompiler.java"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}/test">
<fileset dir="test"/>
</copy>
<copy todir="build/luaj-${version}/examples">
<fileset dir="examples">
<include name="android/*.*"/>
<include name="android/assets/**"/>
<include name="android/res/**"/>
<include name="android/src/**"/>
<include name="jme/*.java"/>
<include name="jse/*.java"/>
<include name="lua/*.*"/>
<include name="maven/pom.xml"/>
<include name="maven/src/**"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}/lib">
<fileset dir=".">
<include name="*-${version}.jar"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}">
<fileset dir=".">
<include name="build.xml"/>
<include name="build-libs.xml"/>
<include name="build-coverage.xml"/>
<include name="version.properties"/>
<include name="wtk.xml"/>
<include name="README.html"/>
<include name="names.csv"/>
<include name=".classpath"/>
<include name=".project"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}/docs">
<fileset dir="docs"/>
</copy>
<zip destfile="luaj-${version}.zip"
basedir="build" includes="luaj-${version}/**"/>
</target>
<target name="mvn_install" depends="jar-jse">
<exec executable="mvn">
<arg value="install:install-file"/>
<arg value="-Dfile=${jar.name.jse}"/>
<arg value="-DgroupId=org.luaj"/>
<arg value="-DartifactId=luaj-jse"/>
<arg value="-Dversion=${version}"/>
<arg value="-Dpackaging=jar"/>
</exec>
</target>
<target name="all" depends="clean,jar-jme,jar-jse,jar-jse-sources"/>
</project>

36
core/pom.xml Normal file
View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.openautonomousconnection.luaj</groupId>
<artifactId>parent</artifactId>
<version>3.0.2</version>
</parent>
<artifactId>core</artifactId>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals><goal>jar</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.release}</source>
<target>${maven.compiler.release}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -26,11 +26,11 @@ import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.Reader; import java.io.Reader;
import org.luaj.vm2.lib.BaseLib; import org.luaj.vm2.libs.BaseLib;
import org.luaj.vm2.lib.DebugLib; import org.luaj.vm2.libs.DebugLib;
import org.luaj.vm2.lib.IoLib; import org.luaj.vm2.libs.IoLib;
import org.luaj.vm2.lib.PackageLib; import org.luaj.vm2.libs.PackageLib;
import org.luaj.vm2.lib.ResourceFinder; import org.luaj.vm2.libs.ResourceFinder;
/** /**
* Global environment used by luaj. Contains global variables referenced by executing lua. * Global environment used by luaj. Contains global variables referenced by executing lua.
@@ -38,8 +38,8 @@ import org.luaj.vm2.lib.ResourceFinder;
* *
* <h3>Constructing and Initializing Instances</h3> * <h3>Constructing and Initializing Instances</h3>
* Typically, this is constructed indirectly by a call to * Typically, this is constructed indirectly by a call to
* {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or * {@link org.luaj.vm2.libs.jse.JsePlatform#standardGlobals()} or
* {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()}, * {@link org.luaj.vm2.libs.jme.JmePlatform#standardGlobals()},
* and then used to load lua scripts for execution as in the following example. * and then used to load lua scripts for execution as in the following example.
* <pre> {@code * <pre> {@code
* Globals globals = JsePlatform.standardGlobals(); * Globals globals = JsePlatform.standardGlobals();
@@ -89,7 +89,7 @@ import org.luaj.vm2.lib.ResourceFinder;
* </ul> * </ul>
* *
* <h3>Lua Environment Variables</h3> * <h3>Lua Environment Variables</h3>
* When using {@link org.luaj.vm2.lib.jse.JsePlatform} or {@link org.luaj.vm2.lib.jme.JmePlatform}, * When using {@link org.luaj.vm2.libs.jse.JsePlatform} or {@link org.luaj.vm2.libs.jme.JmePlatform},
* these environment variables are created within the Globals. * these environment variables are created within the Globals.
* <ul> * <ul>
* <li>"_G" Pointer to this Globals. * <li>"_G" Pointer to this Globals.
@@ -102,8 +102,8 @@ import org.luaj.vm2.lib.ResourceFinder;
* static immutable resources such as class data and string data. * static immutable resources such as class data and string data.
* <p> * <p>
* *
* @see org.luaj.vm2.lib.jse.JsePlatform * @see org.luaj.vm2.libs.jse.JsePlatform
* @see org.luaj.vm2.lib.jme.JmePlatform * @see org.luaj.vm2.libs.jme.JmePlatform
* @see LuaValue * @see LuaValue
* @see Compiler * @see Compiler
* @see Loader * @see Loader
@@ -179,10 +179,22 @@ public class Globals extends LuaTable {
* @throws LuaError if the file could not be loaded. * @throws LuaError if the file could not be loaded.
*/ */
public LuaValue loadfile(String filename) { public LuaValue loadfile(String filename) {
InputStream is = null;
try { try {
return load(finder.findResource(filename), "@"+filename, "bt", this); is = finder.findResource(filename);
if (is == null) {
return error("cannot open " + filename + ": No such file or directory");
}
return load(is, "@"+filename, "bt", this);
} catch (Exception e) { } catch (Exception e) {
return error("load "+filename+": "+e); return error("load "+filename+": "+e);
} finally {
if (is != null) {
try {
is.close();
} catch (Exception ignored) {
}
}
} }
} }

Binary file not shown.

View File

@@ -44,8 +44,8 @@ import java.io.InputStream;
* This should work regardless of which {@link Globals.Compiler} or {@link Globals.Undumper} * This should work regardless of which {@link Globals.Compiler} or {@link Globals.Undumper}
* have been installed. * have been installed.
* <p> * <p>
* By default, when using {@link org.luaj.vm2.lib.jse.JsePlatform} or * By default, when using {@link org.luaj.vm2.libs.jse.JsePlatform} or
* {@link org.luaj.vm2.lib.jme.JmePlatform} * {@link org.luaj.vm2.libs.jme.JmePlatform}
* to construct globals, the {@link LoadState} default undumper is installed * to construct globals, the {@link LoadState} default undumper is installed
* as the default {@link Globals.Undumper}. * as the default {@link Globals.Undumper}.
* <p> * <p>
@@ -155,7 +155,6 @@ public class LoadState {
private static final LuaValue[] NOVALUES = {}; private static final LuaValue[] NOVALUES = {};
private static final Prototype[] NOPROTOS = {}; private static final Prototype[] NOPROTOS = {};
private static final LocVars[] NOLOCVARS = {}; private static final LocVars[] NOLOCVARS = {};
private static final LuaString[] NOSTRVALUES = {};
private static final Upvaldesc[] NOUPVALDESCS = {}; private static final Upvaldesc[] NOUPVALDESCS = {};
private static final int[] NOINTS = {}; private static final int[] NOINTS = {};
@@ -238,12 +237,12 @@ public class LoadState {
int e = (int)((bits >> 52) & 0x7ffL) - 1023; int e = (int)((bits >> 52) & 0x7ffL) - 1023;
if ( e >= 0 && e < 31 ) { if ( e >= 0 && e < 63 ) {
long f = bits & 0xFFFFFFFFFFFFFL; long f = bits & 0xFFFFFFFFFFFFFL;
int shift = 52 - e; int shift = 52 - e;
long intPrecMask = ( 1L << shift ) - 1; long intPrecMask = shift > 0 ? ( 1L << shift ) - 1 : 0;
if ( ( f & intPrecMask ) == 0 ) { if ( shift <= 52 && ( f & intPrecMask ) == 0 ) {
int intValue = (int)( f >> shift ) | ( 1 << e ); long intValue = shift >= 0 ? (f >> shift) | (1L << e) : (f << (-shift)) | (1L << e);
return LuaInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue ); return LuaInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue );
} }
} }

Binary file not shown.

Binary file not shown.

View File

@@ -30,7 +30,7 @@ package org.luaj.vm2;
*/ */
public class Lua { public class Lua {
/** version is supplied by ant build task */ /** version is supplied by ant build task */
public static final String _VERSION = "Luaj 0.0"; public static final String _VERSION = "Lua 5.3";
/** use return values from previous op */ /** use return values from previous op */
public static final int LUA_MULTRET = -1; public static final int LUA_MULTRET = -1;
@@ -80,7 +80,6 @@ public class Lua {
public static final int POS_Bx = POS_C; public static final int POS_Bx = POS_C;
public static final int POS_Ax = POS_A; public static final int POS_Ax = POS_A;
public static final int MAX_OP = ((1<<SIZE_OP)-1); public static final int MAX_OP = ((1<<SIZE_OP)-1);
public static final int MAXARG_A = ((1<<SIZE_A)-1); public static final int MAXARG_A = ((1<<SIZE_A)-1);
public static final int MAXARG_B = ((1<<SIZE_B)-1); public static final int MAXARG_B = ((1<<SIZE_B)-1);
@@ -94,6 +93,7 @@ public class Lua {
public static final int MASK_B = ((1<<SIZE_B)-1)<<POS_B; public static final int MASK_B = ((1<<SIZE_B)-1)<<POS_B;
public static final int MASK_C = ((1<<SIZE_C)-1)<<POS_C; public static final int MASK_C = ((1<<SIZE_C)-1)<<POS_C;
public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx; public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx;
public static final int MASK_Ax = ((1<<SIZE_Ax)-1)<<POS_Ax;
public static final int MASK_NOT_OP = ~MASK_OP; public static final int MASK_NOT_OP = ~MASK_OP;
public static final int MASK_NOT_A = ~MASK_A; public static final int MASK_NOT_A = ~MASK_A;
@@ -200,39 +200,46 @@ public class Lua {
public static final int OP_SUB = 14; /* A B C R(A) := RK(B) - RK(C) */ public static final int OP_SUB = 14; /* A B C R(A) := RK(B) - RK(C) */
public static final int OP_MUL = 15; /* A B C R(A) := RK(B) * RK(C) */ public static final int OP_MUL = 15; /* A B C R(A) := RK(B) * RK(C) */
public static final int OP_DIV = 16; /* A B C R(A) := RK(B) / RK(C) */ public static final int OP_DIV = 16; /* A B C R(A) := RK(B) / RK(C) */
public static final int OP_MOD = 17; /* A B C R(A) := RK(B) % RK(C) */ public static final int OP_IDIV = 17; /* A B C R(A) := RK(B) // RK(C) */
public static final int OP_POW = 18; /* A B C R(A) := RK(B) ^ RK(C) */ public static final int OP_BAND = 18; /* A B C R(A) := RK(B) & RK(C) */
public static final int OP_UNM = 19; /* A B R(A) := -R(B) */ public static final int OP_BOR = 19; /* A B C R(A) := RK(B) | RK(C) */
public static final int OP_NOT = 20; /* A B R(A) := not R(B) */ public static final int OP_BXOR = 20; /* A B C R(A) := RK(B) ~ RK(C) */
public static final int OP_LEN = 21; /* A B R(A) := length of R(B) */ public static final int OP_SHL = 21; /* A B C R(A) := RK(B) << RK(C) */
public static final int OP_SHR = 22; /* A B C R(A) := RK(B) >> RK(C) */
public static final int OP_MOD = 23; /* A B C R(A) := RK(B) % RK(C) */
public static final int OP_POW = 24; /* A B C R(A) := RK(B) ^ RK(C) */
public static final int OP_UNM = 25; /* A B R(A) := -R(B) */
public static final int OP_BNOT = 26; /* A B R(A) := ~R(B) */
public static final int OP_NOT = 27; /* A B R(A) := not R(B) */
public static final int OP_LEN = 28; /* A B R(A) := length of R(B) */
public static final int OP_CONCAT = 22; /* A B C R(A) := R(B).. ... ..R(C) */ public static final int OP_CONCAT = 29; /* A B C R(A) := R(B).. ... ..R(C) */
public static final int OP_JMP = 23; /* sBx pc+=sBx */ public static final int OP_JMP = 30; /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
public static final int OP_EQ = 24; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ public static final int OP_EQ = 31; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
public static final int OP_LT = 25; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ public static final int OP_LT = 32; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
public static final int OP_LE = 26; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ public static final int OP_LE = 33; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
public static final int OP_TEST = 27; /* A C if not (R(A) <=> C) then pc++ */ public static final int OP_TEST = 34; /* A C if not (R(A) <=> C) then pc++ */
public static final int OP_TESTSET = 28; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ public static final int OP_TESTSET = 35; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
public static final int OP_CALL = 29; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ public static final int OP_CALL = 36; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
public static final int OP_TAILCALL = 30; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ public static final int OP_TAILCALL = 37; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
public static final int OP_RETURN = 31; /* A B return R(A), ... ,R(A+B-2) (see note) */ public static final int OP_RETURN = 38; /* A B return R(A), ... ,R(A+B-2) (see note) */
public static final int OP_FORLOOP = 32; /* A sBx R(A)+=R(A+2); public static final int OP_FORLOOP = 39; /* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
public static final int OP_FORPREP = 33; /* A sBx R(A)-=R(A+2); pc+=sBx */ public static final int OP_FORPREP = 40; /* A sBx R(A)-=R(A+2); pc+=sBx */
public static final int OP_TFORCALL = 34; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */ public static final int OP_TFORCALL = 41; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
public static final int OP_TFORLOOP = 35; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */ public static final int OP_TFORLOOP = 42; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
public static final int OP_SETLIST = 36; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ public static final int OP_SETLIST = 43; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
public static final int OP_CLOSURE = 37; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ public static final int OP_CLOSURE = 44; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
public static final int OP_VARARG = 38; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ public static final int OP_VARARG = 45; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
public static final int OP_EXTRAARG = 39; /* Ax extra (larger) argument for previous opcode */ public static final int OP_EXTRAARG = 46; /* Ax extra (larger) argument for previous opcode */
public static final int NUM_OPCODES = OP_EXTRAARG + 1; public static final int NUM_OPCODES = OP_EXTRAARG + 1;
@@ -297,9 +304,16 @@ public class Lua {
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_IDIV */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_BAND */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_BOR */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_BXOR */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SHL */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SHR */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_BNOT */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,692 @@
/*******************************************************************************
* Copyright (c) 2009 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2;
import org.luaj.vm2.libs.DebugLib.CallFrame;
import java.util.ArrayList;
import java.util.List;
/**
* Extension of {@link LuaFunction} which executes lua bytecode.
* <p>
* A {@link LuaClosure} is a combination of a {@link Prototype}
* and a {@link LuaValue} to use as an environment for execution.
* Normally the {@link LuaValue} is a {@link Globals} in which case the environment
* will contain standard lua libraries.
*
* <p>
* There are three main ways {@link LuaClosure} instances are created:
* <ul>
* <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
* <li>Construct it indirectly by loading a chunk via {@link Globals#load(java.io.Reader, String)}
* <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode processing
* </ul>
* <p>
* To construct it directly, the {@link Prototype} is typically created via a compiler such as
* {@link org.luaj.vm2.compiler.LuaC}:
* <pre> {@code
* String script = "print( 'hello, world' )";
* InputStream is = new ByteArrayInputStream(script.getBytes());
* Prototype p = LuaC.instance.compile(is, "script");
* LuaValue globals = JsePlatform.standardGlobals();
* LuaClosure f = new LuaClosure(p, globals);
* f.call();
* }</pre>
* <p>
* To construct it indirectly, the {@link Globals#load(java.io.Reader, String)} method may be used:
* <pre> {@code
* Globals globals = JsePlatform.standardGlobals();
* LuaFunction f = globals.load(new StringReader(script), "script");
* LuaClosure c = f.checkclosure(); // This may fail if LuaJC is installed.
* c.call();
* }</pre>
* <p>
* In this example, the "checkclosure()" may fail if direct lua-to-java-bytecode
* compiling using LuaJC is installed, because no LuaClosure is created in that case
* and the value returned is a {@link LuaFunction} but not a {@link LuaClosure}.
* <p>
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue},
* all the value operations can be used directly such as:
* <ul>
* <li>{@link LuaValue#call()}</li>
* <li>{@link LuaValue#call(LuaValue)}</li>
* <li>{@link LuaValue#invoke()}</li>
* <li>{@link LuaValue#invoke(Varargs)}</li>
* <li>{@link LuaValue#method(String)}</li>
* <li>{@link LuaValue#method(String,LuaValue)}</li>
* <li>{@link LuaValue#invokemethod(String)}</li>
* <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
* <li> ...</li>
* </ul>
* @see LuaValue
* @see LuaFunction
* @see LuaValue#isclosure()
* @see LuaValue#checkclosure()
* @see LuaValue#optclosure(LuaClosure)
* @see LoadState
* @see Globals#compiler
*/
public class LuaClosure extends LuaFunction {
private static final UpValue[] NOUPVALUES = new UpValue[0];
public final Prototype p;
public UpValue[] upValues;
final Globals globals;
/** Create a closure around a Prototype with a specific environment.
* If the prototype has upvalues, the environment will be written into the first upvalue.
* @param p the Prototype to construct this Closure for.
* @param env the environment to associate with the closure.
*/
public LuaClosure(Prototype p, LuaValue env) {
this.p = p;
this.initupvalue1(env);
globals = env instanceof Globals? (Globals) env: null;
}
public void initupvalue1(LuaValue env) {
if (p.upvalues == null || p.upvalues.length == 0)
this.upValues = NOUPVALUES;
else {
this.upValues = new UpValue[p.upvalues.length];
this.upValues[0] = new UpValue(new LuaValue[] {env}, 0);
}
}
public boolean isclosure() {
return true;
}
public LuaClosure optclosure(LuaClosure defval) {
return this;
}
public LuaClosure checkclosure() {
return this;
}
public String tojstring() {
return "function: " + p.toString();
}
private List<LuaValue[]> stackPool = new ArrayList<>();
private LuaValue[] getNewStack() {
if (stackPool.isEmpty()) {
return getNewStackRaw();
} else {
return stackPool.remove(stackPool.size() - 1);
}
}
private LuaValue[] getNewStackRaw() {
int max = p.maxstacksize;
LuaValue[] stack = new LuaValue[max];
System.arraycopy(NILS, 0, stack, 0, max);
return stack;
}
private void releaseStack(LuaValue[] stack) {
System.arraycopy(NILS, 0, stack, 0, stack.length);
stackPool.add(stack);
}
public final LuaValue call() {
LuaValue[] stack = getNewStack();
LuaValue result = execute(stack,NONE).arg1();
releaseStack(stack);
return result;
}
public final LuaValue call(LuaValue arg) {
LuaValue[] stack = getNewStack();
LuaValue result;
switch ( p.numparams ) {
default:
stack[0]=arg;
result = execute(stack,NONE).arg1();
break;
case 0:
result = execute(stack,arg).arg1();
break;
}
releaseStack(stack);
return result;
}
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
LuaValue[] stack = getNewStack();
LuaValue result;
switch ( p.numparams ) {
default:
stack[0]=arg1;
stack[1]=arg2;
result = execute(stack,NONE).arg1();
break;
case 1:
stack[0]=arg1;
result = execute(stack,arg2).arg1();
break;
case 0:
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg1,arg2) : NONE).arg1();
break;
}
releaseStack(stack);
return result;
}
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
LuaValue[] stack = getNewStack();
LuaValue result;
switch ( p.numparams ) {
default:
stack[0]=arg1;
stack[1]=arg2;
stack[2]=arg3;
result = execute(stack,NONE).arg1();
break;
case 2:
stack[0]=arg1;
stack[1]=arg2;
result = execute(stack,arg3).arg1();
break;
case 1:
stack[0]=arg1;
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg2,arg3) : NONE).arg1();
break;
case 0:
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg1,arg2,arg3) : NONE).arg1();
break;
}
releaseStack(stack);
return result;
}
public final Varargs invoke(Varargs varargs) {
return onInvoke(varargs).eval();
}
public final Varargs onInvoke(Varargs varargs) {
LuaValue[] stack = getNewStack();
for ( int i=0; i<p.numparams; i++ )
stack[i] = varargs.arg(i+1);
Varargs result = execute(stack,p.is_vararg!=0 ? varargs.subargs(p.numparams+1) : NONE);
if (result instanceof LuaValue) {
releaseStack(stack);
}
return result;
}
protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
// loop through instructions
int i,a,b,c,pc=0,top=0;
LuaValue o;
Varargs v = NONE;
int[] code = p.code;
LuaValue[] k = p.k;
// upvalues are only possible when closures create closures
// TODO: use linked list.
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
// allow for debug hooks
if (globals != null && globals.debuglib != null)
globals.debuglib.onCall( this, varargs, stack );
// process instructions
try {
for (; true; ++pc) {
if (Thread.currentThread().isInterrupted()) {
throw new LuaError("interrupted");
}
if (globals != null && globals.debuglib != null)
globals.debuglib.onInstruction( pc, v, top );
// pull out instruction
i = code[pc];
a = ((i>>6) & 0xff);
// process the op code
switch ( i & 0x3f ) {
case Lua.OP_MOVE:/* A B R(A):= R(B) */
stack[a] = stack[i>>>23];
continue;
case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */
stack[a] = k[i>>>14];
continue;
case Lua.OP_LOADKX:/* A R(A) := Kst(extra arg) */
++pc;
i = code[pc];
if ((i & 0x3f) != Lua.OP_EXTRAARG) {
int op = i & 0x3f;
throw new LuaError("OP_EXTRAARG expected after OP_LOADKX, got " +
(op < Print.OPNAMES.length - 1 ? Print.OPNAMES[op] : "UNKNOWN_OP_" + op));
}
stack[a] = k[i>>>6];
continue;
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
if ((i&(0x1ff<<14)) != 0)
++pc; /* skip next instruction (if C) */
continue;
case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */
for ( b=i>>>23; b-->=0; )
stack[a++] = LuaValue.NIL;
continue;
case Lua.OP_GETUPVAL: /* A B R(A):= UpValue[B] */
stack[a] = upValues[i>>>23].getValue();
continue;
case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
stack[a] = upValues[i>>>23].getValue().get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_GETTABLE: /* A B C R(A):= R(B)[RK(C)] */
stack[a] = stack[i>>>23].get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SETTABUP: /* A B C UpValue[A][RK(B)] := RK(C) */
upValues[a].getValue().set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */
upValues[i>>>23].setValue(stack[a]);
continue;
case Lua.OP_SETTABLE: /* A B C R(A)[RK(B)]:= RK(C) */
stack[a].set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_NEWTABLE: /* A B C R(A):= {} (size = B,C) */
stack[a] = new LuaTable(i>>>23,(i>>14)&0x1ff);
continue;
case Lua.OP_SELF: /* A B C R(A+1):= R(B): R(A):= R(B)[RK(C)] */
stack[a+1] = (o = stack[i>>>23]);
stack[a] = o.get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_ADD: /* A B C R(A):= RK(B) + RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).add((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SUB: /* A B C R(A):= RK(B) - RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).sub((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_MUL: /* A B C R(A):= RK(B) * RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mul((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_DIV: /* A B C R(A):= RK(B) / RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).div((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_IDIV: /* A B C R(A):= RK(B) // RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).idiv((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_BAND: /* A B C R(A):= RK(B) & RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).band((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_BOR: /* A B C R(A):= RK(B) | RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).bor((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_BXOR: /* A B C R(A):= RK(B) ~ RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).bxor((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SHL: /* A B C R(A):= RK(B) << RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).shl((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SHR: /* A B C R(A):= RK(B) >> RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).shr((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mod((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_POW: /* A B C R(A):= RK(B) ^ RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).pow((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_UNM: /* A B R(A):= -R(B) */
stack[a] = stack[i>>>23].neg();
continue;
case Lua.OP_BNOT: /* A B R(A):= ~R(B) */
stack[a] = stack[i>>>23].bnot();
continue;
case Lua.OP_NOT: /* A B R(A):= not R(B) */
stack[a] = stack[i>>>23].not();
continue;
case Lua.OP_LEN: /* A B R(A):= length of R(B) */
stack[a] = stack[i>>>23].len();
continue;
case Lua.OP_CONCAT: /* A B C R(A):= R(B).. ... ..R(C) */
b = i>>>23;
c = (i>>14)&0x1ff;
{
if ( c > b+1 ) {
Buffer sb = stack[c].buffer();
while ( --c>=b )
sb.concatTo(stack[c]);
stack[a] = sb.value();
} else {
stack[a] = stack[c-1].concat(stack[c]);
}
}
continue;
case Lua.OP_JMP: /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
pc += (i>>>14)-0x1ffff;
if (a > 0) {
for (--a, b = openups.length; --b>=0; )
if (openups[b] != null && openups[b].index >= a) {
openups[b].close();
openups[b] = null;
}
}
continue;
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).eq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
++pc;
continue;
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lt_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
++pc;
continue;
case Lua.OP_LE: /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lteq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
++pc;
continue;
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) )
++pc;
continue;
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
/* note: doc appears to be reversed */
if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) )
++pc;
else
stack[a] = o; // TODO: should be sBx?
continue;
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
switch ( i & (Lua.MASK_B | Lua.MASK_C) ) {
case (1<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(NONE); top=a+v.narg(); continue;
case (2<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(stack[a+1]); top=a+v.narg(); continue;
case (1<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(); continue;
case (2<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1]); continue;
case (3<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2]); continue;
case (4<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
case (1<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(); continue;
case (2<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1]); continue;
case (3<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2]); continue;
case (4<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
default:
b = i>>>23;
c = (i>>14)&0x1ff;
v = stack[a].invoke(b>0?
varargsOf(stack, a+1, b-1): // exact arg count
varargsOf(stack, a+1, top-v.narg()-(a+1), v)); // from prev top
if ( c > 0 ) {
v.copyto(stack, a, c-1);
v = NONE;
} else {
top = a + v.narg();
v = v.dealias();
}
continue;
}
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
switch ( i & Lua.MASK_B ) {
case (1<<Lua.POS_B): return new TailcallVarargs(stack[a], NONE);
case (2<<Lua.POS_B): return new TailcallVarargs(stack[a], stack[a+1]);
case (3<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2]));
case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
default:
b = i>>>23;
v = b>0?
varargsOf(stack,a+1,b-1): // exact arg count
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
return new TailcallVarargs( stack[a], v );
}
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
b = i>>>23;
switch ( b ) {
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
case 1: return NONE;
case 2: return stack[a];
default:
return varargsOf(stack, a, b-1);
}
case Lua.OP_FORLOOP: /* A sBx R(A)+=R(A+2): if R(A) <?= R(A+1) then { pc+=sBx: R(A+3)=R(A) }*/
{
LuaValue limit = stack[a + 1];
LuaValue step = stack[a + 2];
LuaValue idx = stack[a].add(step);
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
stack[a] = idx;
stack[a + 3] = idx;
pc += (i>>>14)-0x1ffff;
}
}
continue;
case Lua.OP_FORPREP: /* A sBx R(A)-=R(A+2): pc+=sBx */
{
LuaValue init = stack[a].checknumber("'for' initial value must be a number");
LuaValue limit = stack[a + 1].checknumber("'for' limit must be a number");
LuaValue step = stack[a + 2].checknumber("'for' step must be a number");
stack[a] = init.sub(step);
stack[a + 1] = limit;
stack[a + 2] = step;
pc += (i>>>14)-0x1ffff;
}
continue;
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
v = stack[a].invoke(varargsOf(stack[a+1],stack[a+2]));
c = (i>>14) & 0x1ff;
while (--c >= 0)
stack[a+3+c] = v.arg(c+1);
v = NONE;
continue;
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
if (!stack[a+1].isnil()) { /* continue loop? */
stack[a] = stack[a+1]; /* save control varible. */
pc += (i>>>14)-0x1ffff;
}
continue;
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
{
if ( (c=(i>>14)&0x1ff) == 0 )
c = code[++pc];
int offset = (c-1) * Lua.LFIELDS_PER_FLUSH;
o = stack[a];
if ( (b=i>>>23) == 0 ) {
b = top - a - 1;
int m = b - v.narg();
int j=1;
for ( ;j<=m; j++ )
o.set(offset+j, stack[a + j]);
for ( ;j<=b; j++ )
o.set(offset+j, v.arg(j-m));
} else {
o.presize( offset + b );
for (int j=1; j<=b; j++)
o.set(offset+j, stack[a + j]);
}
}
continue;
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */
{
Prototype newp = p.p[i>>>14];
LuaClosure ncl = new LuaClosure(newp, globals);
Upvaldesc[] uv = newp.upvalues;
for ( int j=0, nup=uv.length; j<nup; ++j ) {
if (uv[j].instack) /* upvalue refes to local variable? */
ncl.upValues[j] = findupval(stack, uv[j].idx, openups);
else /* get upvalue from enclosing function */
ncl.upValues[j] = upValues[uv[j].idx];
}
stack[a] = ncl;
}
continue;
case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
b = i>>>23;
if ( b == 0 ) {
top = a + (b = varargs.narg());
v = varargs;
} else {
for ( int j=1; j<b; ++j )
stack[a+j-1] = varargs.arg(j);
}
continue;
case Lua.OP_EXTRAARG:
throw new java.lang.IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG");
default:
throw new java.lang.IllegalArgumentException("Illegal opcode: " + (i & 0x3f));
}
}
} catch ( LuaError le ) {
if (le.traceback == null)
processErrorHooks(le, p, pc);
throw le;
} catch ( Exception e ) {
LuaError le = new LuaError(e);
processErrorHooks(le, p, pc);
throw le;
} finally {
if ( openups != null )
for ( int u=openups.length; --u>=0; )
if ( openups[u] != null )
openups[u].close();
if (globals != null && globals.debuglib != null)
globals.debuglib.onReturn();
}
}
/**
* Run the error hook if there is one
* @param msg the message to use in error hook processing.
* */
LuaValue errorHook(LuaValue msgobj, String msg, int level) {
if (globals == null ) return LuaValue.valueOf(msg);
final LuaThread r = globals.running;
if (r.errorfunc == null)
return LuaValue.valueOf(globals.debuglib != null?
msg + "\n" + globals.debuglib.traceback(level):
msg);
final LuaValue e = r.errorfunc;
r.errorfunc = null;
try {
return e.call(msgobj != null ? msgobj : LuaValue.NIL);
} catch ( Throwable t ) {
return LuaValue.valueOf("error in error handling");
} finally {
r.errorfunc = e;
}
}
private void processErrorHooks(LuaError le, Prototype p, int pc) {
String file = "?";
int line = -1;
{
CallFrame frame = null;
if (globals != null && globals.debuglib != null) {
frame = globals.debuglib.getCallFrame(le.level);
if (frame != null) {
String src = frame.shortsource();
file = src != null ? src : "?";
line = frame.currentline();
}
}
if (frame == null) {
file = p.source != null? p.source.tojstring(): "?";
line = p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length ? p.lineinfo[pc] : -1;
}
}
le.fileline = file + ":" + line;
LuaValue error = errorHook(le.getMessageObject(), le.getMessage(), le.level);
le.setMessageObject(error);
le.traceback = error != null ? error.tojstring() : null;
}
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
final int n = openups.length;
for (int i = 0; i < n; ++i)
if (openups[i] != null && openups[i].index == idx)
return openups[i];
for (int i = 0; i < n; ++i)
if (openups[i] == null)
return openups[i] = new UpValue(stack, idx);
error("No space for upvalue");
return null;
}
protected LuaValue getUpvalue(int i) {
return upValues[i].getValue();
}
protected void setUpvalue(int i, LuaValue v) {
upValues[i].setValue(v);
}
public String name() {
return "<"+p.shortsource()+":"+p.linedefined+">";
}
}

Binary file not shown.

View File

@@ -21,7 +21,7 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2; package org.luaj.vm2;
import org.luaj.vm2.lib.MathLib; import org.luaj.vm2.libs.MathLib;
/** /**
* Extension of {@link LuaNumber} which can hold a Java double as its value. * Extension of {@link LuaNumber} which can hold a Java double as its value.
@@ -75,8 +75,13 @@ public class LuaDouble extends LuaNumber {
final double v; final double v;
public static LuaNumber valueOf(double d) { public static LuaNumber valueOf(double d) {
int id = (int) d; if (!Double.isNaN(d) && !Double.isInfinite(d) && d >= Long.MIN_VALUE && d <= Long.MAX_VALUE) {
return d==id? (LuaNumber) LuaInteger.valueOf(id): (LuaNumber) new LuaDouble(d); long ld = (long) d;
if (d == ld) {
return LuaInteger.valueOf(ld);
}
}
return new LuaDouble(d);
} }
/** Don't allow ints to be boxed by DoubleValues */ /** Don't allow ints to be boxed by DoubleValues */
@@ -103,13 +108,14 @@ public class LuaDouble extends LuaNumber {
public double optdouble(double defval) { return v; } public double optdouble(double defval) { return v; }
public int optint(int defval) { return (int) (long) v; } public int optint(int defval) { return (int) (long) v; }
public LuaInteger optinteger(LuaInteger defval) { return LuaInteger.valueOf((int) (long)v); } public LuaInteger optinteger(LuaInteger defval) { return islong()? LuaInteger.valueOf((long) v): defval; }
public long optlong(long defval) { return (long) v; } public long optlong(long defval) { return (long) v; }
public LuaInteger checkinteger() { return LuaInteger.valueOf( (int) (long) v ); } public LuaInteger checkinteger() { if (!islong()) argerror("integer"); return LuaInteger.valueOf((long) v); }
// unary operators // unary operators
public LuaValue neg() { return valueOf(-v); } public LuaValue neg() { return valueOf(-v); }
public LuaValue bnot() { if (!islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(~((long) v)); }
// object equality, used for key comparison // object equality, used for key comparison
public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; } public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
@@ -122,6 +128,7 @@ public class LuaDouble extends LuaNumber {
public boolean raweq( LuaValue val ) { return val.raweq(v); } public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean raweq( double val ) { return v == val; } public boolean raweq( double val ) { return v == val; }
public boolean raweq( int val ) { return v == val; } public boolean raweq( int val ) { return v == val; }
public boolean raweq( long val ) { return v == val; }
// basic binary arithmetic // basic binary arithmetic
public LuaValue add( LuaValue rhs ) { return rhs.add(v); } public LuaValue add( LuaValue rhs ) { return rhs.add(v); }
@@ -139,9 +146,18 @@ public class LuaDouble extends LuaNumber {
public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); } public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); }
public LuaValue idiv( LuaValue rhs ) { return rhs.idivInto(v); }
public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); }
public LuaValue idiv( double rhs ) { return LuaDouble.didiv(v,rhs); }
public LuaValue idiv( int rhs ) { return LuaDouble.didiv(v,rhs); }
public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs,v); }
public LuaValue band( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.band(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) v) & n.tolong()); }
public LuaValue bor( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) v) | n.tolong()); }
public LuaValue bxor( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bxor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) v) ^ n.tolong()); }
public LuaValue shl( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shl(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftLeft((long) v, n.tolong())); }
public LuaValue shr( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shr(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftRight((long) v, n.tolong())); }
public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); } public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); }
public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); }
public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); }
@@ -159,6 +175,10 @@ public class LuaDouble extends LuaNumber {
return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF; return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF;
} }
public static LuaValue didiv(double lhs, double rhs) {
return valueOf(Math.floor(ddiv_d(lhs, rhs)));
}
/** Divide two double numbers according to lua math, and return a double result. /** Divide two double numbers according to lua math, and return a double result.
* @param lhs Left-hand-side of the division. * @param lhs Left-hand-side of the division.
* @param rhs Right-hand-side of the division. * @param rhs Right-hand-side of the division.
@@ -177,7 +197,14 @@ public class LuaDouble extends LuaNumber {
* @see #dmod_d(double, double) * @see #dmod_d(double, double)
*/ */
public static LuaValue dmod(double lhs, double rhs) { public static LuaValue dmod(double lhs, double rhs) {
return rhs!=0? valueOf( lhs-rhs*Math.floor(lhs/rhs) ): NAN; if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return NAN;
if (rhs == Double.POSITIVE_INFINITY) {
return lhs < 0 ? POSINF : valueOf(lhs);
}
if (rhs == Double.NEGATIVE_INFINITY) {
return lhs > 0 ? NEGINF : valueOf(lhs);
}
return valueOf( lhs-rhs*Math.floor(lhs/rhs) );
} }
/** Take modulo for double numbers according to lua math, and return a double result. /** Take modulo for double numbers according to lua math, and return a double result.
@@ -188,32 +215,39 @@ public class LuaDouble extends LuaNumber {
* @see #dmod(double, double) * @see #dmod(double, double)
*/ */
public static double dmod_d(double lhs, double rhs) { public static double dmod_d(double lhs, double rhs) {
return rhs!=0? lhs-rhs*Math.floor(lhs/rhs): Double.NaN; if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return Double.NaN;
if (rhs == Double.POSITIVE_INFINITY) {
return lhs < 0 ? Double.POSITIVE_INFINITY : lhs;
}
if (rhs == Double.NEGATIVE_INFINITY) {
return lhs > 0 ? Double.NEGATIVE_INFINITY : lhs;
}
return lhs-rhs*Math.floor(lhs/rhs);
} }
// relational operators // relational operators
public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? LuaValue.TRUE: FALSE; } public LuaValue lt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gt_b(v)? TRUE: FALSE) : super.lt(rhs); }
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; } public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; } public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); } public boolean lt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gt_b(v) : super.lt_b(rhs); }
public boolean lt_b( int rhs ) { return v < rhs; } public boolean lt_b( int rhs ) { return v < rhs; }
public boolean lt_b( double rhs ) { return v < rhs; } public boolean lt_b( double rhs ) { return v < rhs; }
public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? LuaValue.TRUE: FALSE; } public LuaValue lteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gteq_b(v)? TRUE: FALSE) : super.lteq(rhs); }
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; } public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; } public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); } public boolean lteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gteq_b(v) : super.lteq_b(rhs); }
public boolean lteq_b( int rhs ) { return v <= rhs; } public boolean lteq_b( int rhs ) { return v <= rhs; }
public boolean lteq_b( double rhs ) { return v <= rhs; } public boolean lteq_b( double rhs ) { return v <= rhs; }
public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? LuaValue.TRUE: FALSE; } public LuaValue gt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lt_b(v)? TRUE: FALSE) : super.gt(rhs); }
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; } public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; } public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); } public boolean gt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lt_b(v) : super.gt_b(rhs); }
public boolean gt_b( int rhs ) { return v > rhs; } public boolean gt_b( int rhs ) { return v > rhs; }
public boolean gt_b( double rhs ) { return v > rhs; } public boolean gt_b( double rhs ) { return v > rhs; }
public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? LuaValue.TRUE: FALSE; } public LuaValue gteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lteq_b(v)? TRUE: FALSE) : super.gteq(rhs); }
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; } public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; } public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); } public boolean gteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lteq_b(v) : super.gteq_b(rhs); }
public boolean gteq_b( int rhs ) { return v >= rhs; } public boolean gteq_b( int rhs ) { return v >= rhs; }
public boolean gteq_b( double rhs ) { return v >= rhs; } public boolean gteq_b( double rhs ) { return v >= rhs; }

Binary file not shown.

View File

@@ -76,6 +76,10 @@ public class LuaError extends RuntimeException {
return m != null ? LuaValue.valueOf(m): null; return m != null ? LuaValue.valueOf(m): null;
} }
public void setMessageObject(LuaValue messageObject) {
this.object = messageObject;
}
/** Construct LuaError when a program exception occurs. /** Construct LuaError when a program exception occurs.
* <p> * <p>
* All errors generated from lua code should throw LuaError(String) instead. * All errors generated from lua code should throw LuaError(String) instead.

Binary file not shown.

View File

@@ -25,14 +25,14 @@ package org.luaj.vm2;
/** /**
* Base class for functions implemented in Java. * Base class for functions implemented in Java.
* <p> * <p>
* Direct subclass include {@link org.luaj.vm2.lib.LibFunction} * Direct subclass include {@link org.luaj.vm2.libs.LibFunction}
* which is the base class for * which is the base class for
* all built-in library functions coded in Java, * all built-in library functions coded in Java,
* and {@link LuaClosure}, which represents a lua closure * and {@link LuaClosure}, which represents a lua closure
* whose bytecode is interpreted when the function is invoked. * whose bytecode is interpreted when the function is invoked.
* @see LuaValue * @see LuaValue
* @see LuaClosure * @see LuaClosure
* @see org.luaj.vm2.lib.LibFunction * @see org.luaj.vm2.libs.LibFunction
*/ */
abstract abstract
public class LuaFunction extends LuaValue { public class LuaFunction extends LuaValue {
@@ -74,10 +74,13 @@ public class LuaFunction extends LuaValue {
/** Return the last part of the class name, to be used as a function name in tojstring and elsewhere. /** Return the last part of the class name, to be used as a function name in tojstring and elsewhere.
* @return String naming the last part of the class name after the last dot (.) or dollar sign ($). * @return String naming the last part of the class name after the last dot (.) or dollar sign ($).
* If the first character is '_', it is skipped.
*/ */
public String classnamestub() { public String classnamestub() {
String s = getClass().getName(); String s = getClass().getName();
return s.substring(Math.max(s.lastIndexOf('.'),s.lastIndexOf('$'))+1); int offset = Math.max(s.lastIndexOf('.'), s.lastIndexOf('$')) + 1;
if (s.charAt(offset) == '_') offset++;
return s.substring(offset);
} }
/** Return a human-readable name for this function. Returns the last part of the class name by default. /** Return a human-readable name for this function. Returns the last part of the class name by default.

Binary file not shown.

View File

@@ -21,10 +21,10 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2; package org.luaj.vm2;
import org.luaj.vm2.lib.MathLib; import org.luaj.vm2.libs.MathLib;
/** /**
* Extension of {@link LuaNumber} which can hold a Java int as its value. * Extension of {@link LuaNumber} which can hold a Java long as its value.
* <p> * <p>
* These instance are not instantiated directly by clients, but indirectly * These instance are not instantiated directly by clients, but indirectly
* via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)} * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)}
@@ -59,25 +59,23 @@ public class LuaInteger extends LuaNumber {
* @see LuaValue#valueOf(int) * @see LuaValue#valueOf(int)
* @see LuaValue#valueOf(double) * @see LuaValue#valueOf(double)
*/ */
public static LuaNumber valueOf(long l) { public static LuaInteger valueOf(long l) {
int i = (int) l; int i = (int) l;
return l==i? (i<=255 && i>=-256? intValues[i+256]: return l == i && i <= 255 && i >= -256 ? intValues[i+256] : new LuaInteger(l);
(LuaNumber) new LuaInteger(i)):
(LuaNumber) LuaDouble.valueOf(l);
} }
/** The value being held by this instance. */ /** The value being held by this instance. */
public final int v; public final long v;
/** /**
* Package protected constructor. * Package protected constructor.
* @see LuaValue#valueOf(int) * @see LuaValue#valueOf(int)
**/ **/
LuaInteger(int i) { LuaInteger(long i) {
this.v = i; this.v = i;
} }
public boolean isint() { return true; } public boolean isint() { return v == (int) v; }
public boolean isinttype() { return true; } public boolean isinttype() { return true; }
public boolean islong() { return true; } public boolean islong() { return true; }
@@ -85,33 +83,33 @@ public class LuaInteger extends LuaNumber {
public char tochar() { return (char) v; } public char tochar() { return (char) v; }
public double todouble() { return v; } public double todouble() { return v; }
public float tofloat() { return v; } public float tofloat() { return v; }
public int toint() { return v; } public int toint() { return (int) v; }
public long tolong() { return v; } public long tolong() { return v; }
public short toshort() { return (short) v; } public short toshort() { return (short) v; }
public double optdouble(double defval) { return v; } public double optdouble(double defval) { return v; }
public int optint(int defval) { return v; } public int optint(int defval) { return (int) v; }
public LuaInteger optinteger(LuaInteger defval) { return this; } public LuaInteger optinteger(LuaInteger defval) { return this; }
public long optlong(long defval) { return v; } public long optlong(long defval) { return v; }
public String tojstring() { public String tojstring() {
return Integer.toString(v); return Long.toString(v);
} }
public LuaString strvalue() { public LuaString strvalue() {
return LuaString.valueOf(Integer.toString(v)); return LuaString.valueOf(Long.toString(v));
} }
public LuaString optstring(LuaString defval) { public LuaString optstring(LuaString defval) {
return LuaString.valueOf(Integer.toString(v)); return LuaString.valueOf(Long.toString(v));
} }
public LuaValue tostring() { public LuaValue tostring() {
return LuaString.valueOf(Integer.toString(v)); return LuaString.valueOf(Long.toString(v));
} }
public String optjstring(String defval) { public String optjstring(String defval) {
return Integer.toString(v); return Long.toString(v);
} }
public LuaInteger checkinteger() { public LuaInteger checkinteger() {
@@ -123,15 +121,16 @@ public class LuaInteger extends LuaNumber {
} }
public int hashCode() { public int hashCode() {
return v; return hashCode(v);
} }
public static int hashCode(int x) { public static int hashCode(long x) {
return x; return (int) (x ^ (x >>> 32));
} }
// unary operators // unary operators
public LuaValue neg() { return valueOf(-(long)v); } public LuaValue neg() { return valueOf(-(long)v); }
public LuaValue bnot() { return valueOf(~v); }
// object equality, used for key comparison // object equality, used for key comparison
public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; } public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; }
@@ -144,56 +143,66 @@ public class LuaInteger extends LuaNumber {
public boolean raweq( LuaValue val ) { return val.raweq(v); } public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean raweq( double val ) { return v == val; } public boolean raweq( double val ) { return v == val; }
public boolean raweq( int val ) { return v == val; } public boolean raweq( int val ) { return v == val; }
public boolean raweq( long val ) { return v == val; }
// arithmetic operators // arithmetic operators
public LuaValue add( LuaValue rhs ) { return rhs.add(v); } public LuaValue add( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.add(rhs): (n.isinttype()? LuaInteger.valueOf(v + n.tolong()): LuaDouble.valueOf(v + n.todouble())); }
public LuaValue add( double lhs ) { return LuaDouble.valueOf(lhs + v); } public LuaValue add( double lhs ) { return LuaDouble.valueOf(lhs + v); }
public LuaValue add( int lhs ) { return LuaInteger.valueOf(lhs + (long)v); } public LuaValue add( int lhs ) { return LuaInteger.valueOf(lhs + v); }
public LuaValue sub( LuaValue rhs ) { return rhs.subFrom(v); } public LuaValue sub( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.sub(rhs): (n.isinttype()? LuaInteger.valueOf(v - n.tolong()): LuaDouble.valueOf(v - n.todouble())); }
public LuaValue sub( double rhs ) { return LuaDouble.valueOf(v - rhs); } public LuaValue sub( double rhs ) { return LuaDouble.valueOf(v - rhs); }
public LuaValue sub( int rhs ) { return LuaDouble.valueOf(v - rhs); } public LuaValue sub( int rhs ) { return LuaInteger.valueOf(v - rhs); }
public LuaValue subFrom( double lhs ) { return LuaDouble.valueOf(lhs - v); } public LuaValue subFrom( double lhs ) { return LuaDouble.valueOf(lhs - v); }
public LuaValue subFrom( int lhs ) { return LuaInteger.valueOf(lhs - (long)v); } public LuaValue subFrom( int lhs ) { return LuaInteger.valueOf(lhs - v); }
public LuaValue mul( LuaValue rhs ) { return rhs.mul(v); } public LuaValue mul( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.mul(rhs): (n.isinttype()? LuaInteger.valueOf(v * n.tolong()): LuaDouble.valueOf(v * n.todouble())); }
public LuaValue mul( double lhs ) { return LuaDouble.valueOf(lhs * v); } public LuaValue mul( double lhs ) { return LuaDouble.valueOf(lhs * v); }
public LuaValue mul( int lhs ) { return LuaInteger.valueOf(lhs * (long)v); } public LuaValue mul( int lhs ) { return LuaInteger.valueOf(lhs * v); }
public LuaValue pow( LuaValue rhs ) { return rhs.powWith(v); } public LuaValue pow( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.pow(rhs): MathLib.dpow(v, n.todouble()); }
public LuaValue pow( double rhs ) { return MathLib.dpow(v,rhs); } public LuaValue pow( double rhs ) { return MathLib.dpow(v,rhs); }
public LuaValue pow( int rhs ) { return MathLib.dpow(v,rhs); } public LuaValue pow( int rhs ) { return MathLib.dpow(v,rhs); }
public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); } public LuaValue div( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.div(rhs): LuaDouble.ddiv(v, n.todouble()); }
public LuaValue idiv( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.idiv(rhs): (n.isinttype()? LuaInteger.valueOf(luaFloorDiv(v, n.tolong())): LuaDouble.didiv(v, n.todouble())); }
public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); }
public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); } public LuaValue idiv( double rhs ) { return LuaDouble.didiv(v,rhs); }
public LuaValue idiv( int rhs ) { return LuaInteger.valueOf(luaFloorDiv(v, rhs)); }
public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs,v); }
public LuaValue band( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.band(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(v & n.tolong()); }
public LuaValue bor( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bor(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(v | n.tolong()); }
public LuaValue bxor( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bxor(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(v ^ n.tolong()); }
public LuaValue shl( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shl(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(luaShiftLeft(v, n.tolong())); }
public LuaValue shr( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shr(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(luaShiftRight(v, n.tolong())); }
public LuaValue mod( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.mod(rhs): (n.isinttype()? LuaInteger.valueOf(luaFloorMod(v, n.tolong())): LuaDouble.dmod(v, n.todouble())); }
public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); }
public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( int rhs ) { return LuaInteger.valueOf(luaFloorMod(v, rhs)); }
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); } public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); }
// relational operators // relational operators
public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? TRUE: FALSE; } public LuaValue lt( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lt(rhs): (n.isinttype()? (v < n.tolong()? TRUE: FALSE): (v < n.todouble()? TRUE: FALSE)); }
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; } public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; } public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); } public boolean lt_b( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lt_b(rhs): (n.isinttype()? v < n.tolong(): v < n.todouble()); }
public boolean lt_b( int rhs ) { return v < rhs; } public boolean lt_b( int rhs ) { return v < rhs; }
public boolean lt_b( double rhs ) { return v < rhs; } public boolean lt_b( double rhs ) { return v < rhs; }
public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? TRUE: FALSE; } public LuaValue lteq( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lteq(rhs): (n.isinttype()? (v <= n.tolong()? TRUE: FALSE): (v <= n.todouble()? TRUE: FALSE)); }
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; } public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; } public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); } public boolean lteq_b( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lteq_b(rhs): (n.isinttype()? v <= n.tolong(): v <= n.todouble()); }
public boolean lteq_b( int rhs ) { return v <= rhs; } public boolean lteq_b( int rhs ) { return v <= rhs; }
public boolean lteq_b( double rhs ) { return v <= rhs; } public boolean lteq_b( double rhs ) { return v <= rhs; }
public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? TRUE: FALSE; } public LuaValue gt( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gt(rhs): (n.isinttype()? (v > n.tolong()? TRUE: FALSE): (v > n.todouble()? TRUE: FALSE)); }
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; } public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; } public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); } public boolean gt_b( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gt_b(rhs): (n.isinttype()? v > n.tolong(): v > n.todouble()); }
public boolean gt_b( int rhs ) { return v > rhs; } public boolean gt_b( int rhs ) { return v > rhs; }
public boolean gt_b( double rhs ) { return v > rhs; } public boolean gt_b( double rhs ) { return v > rhs; }
public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? TRUE: FALSE; } public LuaValue gteq( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gteq(rhs): (n.isinttype()? (v >= n.tolong()? TRUE: FALSE): (v >= n.todouble()? TRUE: FALSE)); }
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; } public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; } public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); } public boolean gteq_b( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gteq_b(rhs): (n.isinttype()? v >= n.tolong(): v >= n.todouble()); }
public boolean gteq_b( int rhs ) { return v >= rhs; } public boolean gteq_b( int rhs ) { return v >= rhs; }
public boolean gteq_b( double rhs ) { return v >= rhs; } public boolean gteq_b( double rhs ) { return v >= rhs; }
@@ -201,7 +210,7 @@ public class LuaInteger extends LuaNumber {
public int strcmp( LuaString rhs ) { typerror("attempt to compare number with string"); return 0; } public int strcmp( LuaString rhs ) { typerror("attempt to compare number with string"); return 0; }
public int checkint() { public int checkint() {
return v; return (int) v;
} }
public long checklong() { public long checklong() {
return v; return v;
@@ -216,4 +225,41 @@ public class LuaInteger extends LuaNumber {
return valueOf( String.valueOf(v) ); return valueOf( String.valueOf(v) );
} }
private static long luaFloorDiv(long lhs, long rhs) {
if (rhs == 0) {
throw new LuaError("attempt to divide by zero");
}
long quotient = lhs / rhs;
long remainder = lhs % rhs;
if (remainder != 0 && ((lhs ^ rhs) < 0)) {
quotient--;
}
return quotient;
}
private static long luaFloorMod(long lhs, long rhs) {
if (rhs == 0) {
throw new LuaError("attempt to divide by zero");
}
return lhs - rhs * luaFloorDiv(lhs, rhs);
}
static long luaShiftLeft(long lhs, long rhs) {
if (rhs < 0) {
return luaShiftRight(lhs, -rhs);
}
return rhs >= Long.SIZE ? 0L : lhs << rhs;
}
static long luaShiftRight(long lhs, long rhs) {
if (rhs < 0) {
return luaShiftLeft(lhs, -rhs);
}
return rhs >= Long.SIZE ? 0L : lhs >>> rhs;
}
private static LuaError bitwiseError() {
return new LuaError("number has no integer representation");
}
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -28,7 +28,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import org.luaj.vm2.lib.MathLib; import org.luaj.vm2.libs.MathLib;
/** /**
* Subclass of {@link LuaValue} for representing lua strings. * Subclass of {@link LuaValue} for representing lua strings.
@@ -144,7 +144,7 @@ public class LuaString extends LuaValue {
/** Construct a new LuaString using a copy of the bytes array supplied */ /** Construct a new LuaString using a copy of the bytes array supplied */
private static LuaString valueFromCopy(byte[] bytes, int off, int len) { private static LuaString valueFromCopy(byte[] bytes, int off, int len) {
final byte[] copy = new byte[len]; final byte[] copy = new byte[len];
for (int i=0; i<len; ++i) copy[i] = bytes[off+i]; System.arraycopy(bytes, off, copy, 0, len);
return new LuaString(copy, 0, len); return new LuaString(copy, 0, len);
} }
@@ -262,6 +262,7 @@ public class LuaString extends LuaValue {
// unary operators // unary operators
public LuaValue neg() { double d = scannumber(); return Double.isNaN(d)? super.neg(): valueOf(-d); } public LuaValue neg() { double d = scannumber(); return Double.isNaN(d)? super.neg(): valueOf(-d); }
public LuaValue bnot() { double d = scannumber(); if (Double.isNaN(d)) return super.bnot(); if (d != (long) d) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(~((long) d)); }
// basic binary arithmetic // basic binary arithmetic
public LuaValue add( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); } public LuaValue add( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); }
@@ -280,29 +281,38 @@ public class LuaString extends LuaValue {
public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs, checkarith()); } public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs, checkarith()); }
public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs, checkarith()); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs, checkarith()); }
public LuaValue div( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); } public LuaValue div( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); }
public LuaValue idiv( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(IDIV,rhs): rhs.idivInto(d); }
public LuaValue div( double rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(checkarith(),rhs); }
public LuaValue div( int rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(checkarith(),rhs); }
public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs, checkarith()); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs, checkarith()); }
public LuaValue idiv( double rhs ) { return LuaDouble.didiv(checkarith(),rhs); }
public LuaValue idiv( int rhs ) { return LuaDouble.didiv(checkarith(),rhs); }
public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs, checkarith()); }
public LuaValue band( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.band(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.band(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) d) & n.tolong()); }
public LuaValue bor( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.bor(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) d) | n.tolong()); }
public LuaValue bxor( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.bxor(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bxor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) d) ^ n.tolong()); }
public LuaValue shl( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.shl(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shl(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftLeft((long) d, n.tolong())); }
public LuaValue shr( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.shr(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shr(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftRight((long) d, n.tolong())); }
public LuaValue mod( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); } public LuaValue mod( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); }
public LuaValue mod( double rhs ) { return LuaDouble.dmod(checkarith(), rhs); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(checkarith(), rhs); }
public LuaValue mod( int rhs ) { return LuaDouble.dmod(checkarith(), rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(checkarith(), rhs); }
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); } public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); }
// relational operators, these only work with other strings // relational operators, these only work with other strings
public LuaValue lt( LuaValue rhs ) { return rhs.strcmp(this)>0? LuaValue.TRUE: FALSE; } public LuaValue lt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>0? LuaValue.TRUE: FALSE) : super.lt(rhs); }
public boolean lt_b( LuaValue rhs ) { return rhs.strcmp(this)>0; } public boolean lt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>0 : super.lt_b(rhs); }
public boolean lt_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lt_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
public boolean lt_b( double rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lt_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
public LuaValue lteq( LuaValue rhs ) { return rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE; } public LuaValue lteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE) : super.lteq(rhs); }
public boolean lteq_b( LuaValue rhs ) { return rhs.strcmp(this)>=0; } public boolean lteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>=0 : super.lteq_b(rhs); }
public boolean lteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
public boolean lteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
public LuaValue gt( LuaValue rhs ) { return rhs.strcmp(this)<0? LuaValue.TRUE: FALSE; } public LuaValue gt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<0? LuaValue.TRUE: FALSE) : super.gt(rhs); }
public boolean gt_b( LuaValue rhs ) { return rhs.strcmp(this)<0; } public boolean gt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<0 : super.gt_b(rhs); }
public boolean gt_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gt_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
public boolean gt_b( double rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gt_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
public LuaValue gteq( LuaValue rhs ) { return rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE; } public LuaValue gteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE) : super.gteq(rhs); }
public boolean gteq_b( LuaValue rhs ) { return rhs.strcmp(this)<=0; } public boolean gteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<=0 : super.gteq_b(rhs); }
public boolean gteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
public boolean gteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
@@ -340,10 +350,16 @@ public class LuaString extends LuaValue {
return (int) (long) checkdouble(); return (int) (long) checkdouble();
} }
public LuaInteger checkinteger() { public LuaInteger checkinteger() {
return valueOf(checkint()); double d = scannumber();
if (Double.isNaN(d) || d != (long) d)
argerror("integer");
return LuaInteger.valueOf((long) d);
} }
public long checklong() { public long checklong() {
return (long) checkdouble(); double d = scannumber();
if (Double.isNaN(d) || d != (long) d)
argerror("integer");
return (long) d;
} }
public double checkdouble() { public double checkdouble() {
double d = scannumber(); double d = scannumber();
@@ -391,23 +407,23 @@ public class LuaString extends LuaValue {
public short toshort() { return (short) toint(); } public short toshort() { return (short) toint(); }
public double optdouble(double defval) { public double optdouble(double defval) {
return checknumber().checkdouble(); return checkdouble();
} }
public int optint(int defval) { public int optint(int defval) {
return checknumber().checkint(); return checkint();
} }
public LuaInteger optinteger(LuaInteger defval) { public LuaInteger optinteger(LuaInteger defval) {
return checknumber().checkinteger(); return checkinteger();
} }
public long optlong(long defval) { public long optlong(long defval) {
return checknumber().checklong(); return checklong();
} }
public LuaNumber optnumber(LuaNumber defval) { public LuaNumber optnumber(LuaNumber defval) {
return checknumber().checknumber(); return checknumber();
} }
public LuaString optstring(LuaString defval) { public LuaString optstring(LuaString defval) {
@@ -761,8 +777,11 @@ public class LuaString extends LuaValue {
while ( i<j && m_bytes[j-1]==' ' ) --j; while ( i<j && m_bytes[j-1]==' ' ) --j;
if ( i>=j ) if ( i>=j )
return Double.NaN; return Double.NaN;
if ( m_bytes[i]=='0' && i+1<j && (m_bytes[i+1]=='x'||m_bytes[i+1]=='X')) int prefix = (m_bytes[i] == '+' || m_bytes[i] == '-') ? i + 1 : i;
return scanlong(16, i+2, j); if (prefix + 1 < j && m_bytes[prefix]=='0' && (m_bytes[prefix+1]=='x'||m_bytes[prefix+1]=='X')) {
double l = scanlong(16, prefix + 2, j, i != prefix);
return Double.isNaN(l)? scandouble(i,j): l;
}
double l = scanlong(10, i, j); double l = scanlong(10, i, j);
return Double.isNaN(l)? scandouble(i,j): l; return Double.isNaN(l)? scandouble(i,j): l;
} }
@@ -792,9 +811,15 @@ public class LuaString extends LuaValue {
* or Double.NaN if not * or Double.NaN if not
*/ */
private double scanlong( int base, int start, int end ) { private double scanlong( int base, int start, int end ) {
return scanlong(base, start, end, false);
}
private double scanlong( int base, int start, int end, boolean hasSign ) {
long x = 0; long x = 0;
boolean neg = (m_bytes[start] == '-'); boolean neg = hasSign && m_bytes[start - 1] == '-';
for ( int i=(neg?start+1:start); i<end; i++ ) { if (start >= end)
return Double.NaN;
for ( int i=start; i<end; i++ ) {
int digit = m_bytes[i] - (base<=10||(m_bytes[i]>='0'&&m_bytes[i]<='9')? '0': int digit = m_bytes[i] - (base<=10||(m_bytes[i]>='0'&&m_bytes[i]<='9')? '0':
m_bytes[i]>='A'&&m_bytes[i]<='Z'? ('A'-10): ('a'-10)); m_bytes[i]>='A'&&m_bytes[i]<='Z'? ('A'-10): ('a'-10));
if ( digit < 0 || digit >= base ) if ( digit < 0 || digit >= base )

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -236,7 +236,7 @@ public class LuaTable extends LuaValue implements Metatable {
} }
public LuaValue rawget( LuaValue key ) { public LuaValue rawget( LuaValue key ) {
if ( key.isinttype() ) { if ( key.isint() ) {
int ikey = key.toint(); int ikey = key.toint();
if ( ikey>0 && ikey<=array.length ) { if ( ikey>0 && ikey<=array.length ) {
LuaValue v = m_metatable == null LuaValue v = m_metatable == null
@@ -266,8 +266,8 @@ public class LuaTable extends LuaValue implements Metatable {
/** caller must ensure key is not nil */ /** caller must ensure key is not nil */
public void set( LuaValue key, LuaValue value ) { public void set( LuaValue key, LuaValue value ) {
if (!key.isvalidkey() && !metatag(NEWINDEX).isfunction()) if (key == null || !key.isvalidkey() && !metatag(NEWINDEX).isfunction())
typerror("table index"); throw new LuaError("value ('" + key + "') can not be used as a table index");
if ( m_metatable==null || ! rawget(key).isnil() || ! settable(this,key,value) ) if ( m_metatable==null || ! rawget(key).isnil() || ! settable(this,key,value) )
rawset(key, value); rawset(key, value);
} }
@@ -279,7 +279,7 @@ public class LuaTable extends LuaValue implements Metatable {
/** caller must ensure key is not nil */ /** caller must ensure key is not nil */
public void rawset( LuaValue key, LuaValue value ) { public void rawset( LuaValue key, LuaValue value ) {
if ( !key.isinttype() || !arrayset(key.toint(), value) ) if ( !key.isint() || !arrayset(key.toint(), value) )
hashset( key, value ); hashset( key, value );
} }
@@ -299,15 +299,15 @@ public class LuaTable extends LuaValue implements Metatable {
* @return The removed item, or {@link #NONE} if not removed * @return The removed item, or {@link #NONE} if not removed
*/ */
public LuaValue remove(int pos) { public LuaValue remove(int pos) {
int n = rawlen(); int n = length();
if ( pos == 0 ) if ( pos == 0 )
pos = n; pos = n;
else if (pos > n) else if (pos > n)
return NONE; return NONE;
LuaValue v = rawget(pos); LuaValue v = get(pos);
for ( LuaValue r=v; !r.isnil(); ) { for ( LuaValue r=v; !r.isnil(); ) {
r = rawget(pos+1); r = get(pos+1);
rawset(pos++, r); set(pos++, r);
} }
return v.isnil()? NONE: v; return v.isnil()? NONE: v;
} }
@@ -319,10 +319,10 @@ public class LuaTable extends LuaValue implements Metatable {
*/ */
public void insert(int pos, LuaValue value) { public void insert(int pos, LuaValue value) {
if ( pos == 0 ) if ( pos == 0 )
pos = rawlen()+1; pos = length()+1;
while ( ! value.isnil() ) { while ( ! value.isnil() ) {
LuaValue v = rawget( pos ); LuaValue v = get( pos );
rawset(pos++, value); set(pos++, value);
value = v; value = v;
} }
} }
@@ -347,7 +347,12 @@ public class LuaTable extends LuaValue implements Metatable {
} }
public int length() { public int length() {
return m_metatable != null? len().toint(): rawlen(); if (m_metatable != null) {
LuaValue len = len();
if (!len.isint()) throw new LuaError("table length is not an integer: " + len);
return len.toint();
}
return rawlen();
} }
public LuaValue len() { public LuaValue len() {
@@ -383,14 +388,14 @@ public class LuaTable extends LuaValue implements Metatable {
do { do {
// find current key index // find current key index
if ( ! key.isnil() ) { if ( ! key.isnil() ) {
if ( key.isinttype() ) { if ( key.isint() ) {
i = key.toint(); i = key.toint();
if ( i>0 && i<=array.length ) { if ( i>0 && i<=array.length ) {
break; break;
} }
} }
if ( hash.length == 0 ) if ( hash.length == 0 )
error( "invalid key to 'next'" ); error( "invalid key to 'next' 1: " + key );
i = hashSlot( key ); i = hashSlot( key );
boolean found = false; boolean found = false;
for ( Slot slot = hash[i]; slot != null; slot = slot.rest() ) { for ( Slot slot = hash[i]; slot != null; slot = slot.rest() ) {
@@ -404,7 +409,7 @@ public class LuaTable extends LuaValue implements Metatable {
} }
} }
if ( !found ) { if ( !found ) {
error( "invalid key to 'next'" ); error( "invalid key to 'next' 2: " + key );
} }
i += 1+array.length; i += 1+array.length;
} }
@@ -467,7 +472,8 @@ public class LuaTable extends LuaValue implements Metatable {
} }
} }
if ( checkLoadFactor() ) { if ( checkLoadFactor() ) {
if ( key.isinttype() && key.toint() > 0 ) { if ( (m_metatable == null || !m_metatable.useWeakValues())
&& key.isint() && key.toint() > 0 ) {
// a rehash might make room in the array portion for this key. // a rehash might make room in the array portion for this key.
rehash( key.toint() ); rehash( key.toint() );
if ( arrayset(key.toint(), value) ) if ( arrayset(key.toint(), value) )
@@ -714,7 +720,7 @@ public class LuaTable extends LuaValue implements Metatable {
StrongSlot entry = slot.first(); StrongSlot entry = slot.first();
if (entry != null) if (entry != null)
newArray[ k - 1 ] = entry.value(); newArray[ k - 1 ] = entry.value();
} else { } else if ( !(slot instanceof DeadSlot) ) {
int j = slot.keyindex( newHashMask ); int j = slot.keyindex( newHashMask );
newHash[j] = slot.relink( newHash[j] ); newHash[j] = slot.relink( newHash[j] );
} }
@@ -761,9 +767,9 @@ public class LuaTable extends LuaValue implements Metatable {
} }
protected static Entry defaultEntry(LuaValue key, LuaValue value) { protected static Entry defaultEntry(LuaValue key, LuaValue value) {
if ( key.isinttype() ) { if ( key.isint() ) {
return new IntKeyEntry( key.toint(), value ); return new IntKeyEntry( key.toint(), value );
} else if (value.type() == TNUMBER) { } else if (value.type() == TNUMBER && !value.isinttype()) {
return new NumberValueEntry( key, value.todouble() ); return new NumberValueEntry( key, value.todouble() );
} else { } else {
return new NormalEntry( key, value ); return new NormalEntry( key, value );
@@ -780,36 +786,39 @@ public class LuaTable extends LuaValue implements Metatable {
* @param comparator {@link LuaValue} to be called to compare elements. * @param comparator {@link LuaValue} to be called to compare elements.
*/ */
public void sort(LuaValue comparator) { public void sort(LuaValue comparator) {
if (len().tolong() >= (long)Integer.MAX_VALUE) throw new LuaError("array too big: " + len().tolong());
if (m_metatable != null && m_metatable.useWeakValues()) { if (m_metatable != null && m_metatable.useWeakValues()) {
dropWeakArrayValues(); dropWeakArrayValues();
} }
int n = array.length; int n = length();
while ( n > 0 && array[n-1] == null )
--n;
if ( n > 1 ) if ( n > 1 )
heapSort(n, comparator); heapSort(n, comparator.isnil() ? null : comparator);
} }
private void heapSort(int count, LuaValue cmpfunc) { private void heapSort(int count, LuaValue cmpfunc) {
heapify(count, cmpfunc); heapify(count, cmpfunc);
for ( int end=count-1; end>0; ) { for ( int end=count; end>1; ) {
swap(end, 0); LuaValue a = get(end); // swap(end, 1)
siftDown(0, --end, cmpfunc); set(end, get(1));
set(1, a);
siftDown(1, --end, cmpfunc);
} }
} }
private void heapify(int count, LuaValue cmpfunc) { private void heapify(int count, LuaValue cmpfunc) {
for ( int start=count/2-1; start>=0; --start ) for ( int start=count/2; start>0; --start )
siftDown(start, count - 1, cmpfunc); siftDown(start, count, cmpfunc);
} }
private void siftDown(int start, int end, LuaValue cmpfunc) { private void siftDown(int start, int end, LuaValue cmpfunc) {
for ( int root=start; root*2+1 <= end; ) { for ( int root=start; root*2 <= end; ) {
int child = root*2+1; int child = root*2;
if (child < end && compare(child, child + 1, cmpfunc)) if (child < end && compare(child, child + 1, cmpfunc))
++child; ++child;
if (compare(root, child, cmpfunc)) { if (compare(root, child, cmpfunc)) {
swap(root, child); LuaValue a = get(root); // swap(root, child)
set(root, get(child));
set(child, a);
root = child; root = child;
} else } else
return; return;
@@ -817,29 +826,16 @@ public class LuaTable extends LuaValue implements Metatable {
} }
private boolean compare(int i, int j, LuaValue cmpfunc) { private boolean compare(int i, int j, LuaValue cmpfunc) {
LuaValue a, b; LuaValue a = get(i), b = get(j);
if (m_metatable == null) {
a = array[i];
b = array[j];
} else {
a = m_metatable.arrayget(array, i);
b = m_metatable.arrayget(array, j);
}
if ( a == null || b == null ) if ( a == null || b == null )
return false; return false;
if ( ! cmpfunc.isnil() ) { if ( cmpfunc != null ) {
return cmpfunc.call(a,b).toboolean(); return cmpfunc.call(a,b).toboolean();
} else { } else {
return a.lt_b(b); return a.lt_b(b);
} }
} }
private void swap(int i, int j) {
LuaValue a = array[i];
array[i] = array[j];
array[j] = a;
}
/** This may be deprecated in a future release. /** This may be deprecated in a future release.
* It is recommended to count via iteration over next() instead * It is recommended to count via iteration over next() instead
* @return count of keys in the table * @return count of keys in the table
@@ -892,6 +888,11 @@ public class LuaTable extends LuaValue implements Metatable {
/** Unpack the elements from i to j inclusive */ /** Unpack the elements from i to j inclusive */
public Varargs unpack(int i, int j) { public Varargs unpack(int i, int j) {
if (j < i) return NONE;
int count = j - i;
if (count < 0) throw new LuaError("too many results to unpack: greater " + Integer.MAX_VALUE); // integer overflow
int max = 0x00ffffff;
if (count >= max) throw new LuaError("too many results to unpack: " + count + " (max is " + max + ')');
int n = j + 1 - i; int n = j + 1 - i;
switch (n) { switch (n) {
case 0: return NONE; case 0: return NONE;
@@ -900,10 +901,14 @@ public class LuaTable extends LuaValue implements Metatable {
default: default:
if (n < 0) if (n < 0)
return NONE; return NONE;
try {
LuaValue[] v = new LuaValue[n]; LuaValue[] v = new LuaValue[n];
while (--n >= 0) while (--n >= 0)
v[n] = get(i+n); v[n] = get(i+n);
return varargsOf(v); return varargsOf(v);
} catch (OutOfMemoryError e) {
throw new LuaError("too many results to unpack [out of memory]: " + n);
}
} }
} }
@@ -1231,14 +1236,15 @@ public class LuaTable extends LuaValue implements Metatable {
} }
public Entry set(LuaValue value) { public Entry set(LuaValue value) {
if (value.type() == TNUMBER) {
LuaValue n = value.tonumber(); LuaValue n = value.tonumber();
if ( !n.isnil() ) { if (!n.isnil()) {
this.value = n.todouble(); this.value = n.todouble();
return this; return this;
} else {
return new NormalEntry( this.key, value );
} }
} }
return new NormalEntry( this.key, value );
}
public int keyindex( int mask ) { public int keyindex( int mask ) {
return hashSlot( key, mask ); return hashSlot( key, mask );

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,309 @@
/*******************************************************************************
* Copyright (c) 2007-2012 LuaJ. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Subclass of {@link LuaValue} that implements
* a lua coroutine thread using Java Threads.
* <p>
* A LuaThread is typically created in response to a scripted call to
* {@code coroutine.create()}
* <p>
* The threads must be initialized with the globals, so that
* the global environment may be passed along according to rules of lua.
* This is done via the constructor arguments {@link #LuaThread(Globals)} or
* {@link #LuaThread(Globals, LuaValue)}.
* <p>
* The utility classes {@link org.luaj.vm2.libs.jse.JsePlatform} and
* {@link org.luaj.vm2.libs.jme.JmePlatform}
* see to it that this {@link Globals} are initialized properly.
* <p>
* The behavior of coroutine threads matches closely the behavior
* of C coroutine library. However, because of the use of Java threads
* to manage call state, it is possible to yield from anywhere in luaj.
* <p>
* Each Java thread wakes up at regular intervals and checks a weak reference
* to determine if it can ever be resumed. If not, it throws
* {@link OrphanedThread} which is an {@link java.lang.Error}.
* Applications should not catch {@link OrphanedThread}, because it can break
* the thread safety of luaj. The value controlling the polling interval
* is {@link #thread_orphan_check_interval} and may be set by the user.
* <p>
* There are two main ways to abandon a coroutine. The first is to call
* {@code yield()} from lua, or equivalently {@link Globals#yield(Varargs)},
* and arrange to have it never resumed possibly by values passed to yield.
* The second is to throw {@link OrphanedThread}, which should put the thread
* in a dead state. In either case all references to the thread must be
* dropped, and the garbage collector must run for the thread to be
* garbage collected.
*
*
* @see LuaValue
* @see org.luaj.vm2.libs.jse.JsePlatform
* @see org.luaj.vm2.libs.jme.JmePlatform
* @see org.luaj.vm2.libs.CoroutineLib
*/
public class LuaThread extends LuaValue {
/** Shared metatable for lua threads. */
public static LuaValue s_metatable;
/** The current number of coroutines. Should not be set. */
public static int coroutine_count = 0;
/** Polling interval, in milliseconds, which each thread uses while waiting to
* return from a yielded state to check if the lua threads is no longer
* referenced and therefore should be garbage collected.
* A short polling interval for many threads will consume server resources.
* Orphaned threads cannot be detected and collected unless garbage
* collection is run. This can be changed by Java startup code if desired.
*/
public static long thread_orphan_check_interval = 5000;
public static final String USE_PLATFORM_THREAD = "USE_PLATFORM_THREAD";
private static boolean SUPPORT_VIRTUAL_THREAD = false;
static {
try {
Thread.class.getMethod("ofVirtual");
SUPPORT_VIRTUAL_THREAD = true;
} catch (Exception e) {
//e.printStackTrace();
}
}
public static final int STATUS_INITIAL = 0;
public static final int STATUS_SUSPENDED = 1;
public static final int STATUS_RUNNING = 2;
public static final int STATUS_NORMAL = 3;
public static final int STATUS_DEAD = 4;
public static final String[] STATUS_NAMES = {
"suspended",
"suspended",
"running",
"normal",
"dead",};
public final State state;
public static final int MAX_CALLSTACK = 256;
/** Thread-local used by DebugLib to store debugging state.
* This is an opaque value that should not be modified by applications. */
public Object callstack;
public final Globals globals;
/** Error message handler for this thread, if any. */
public LuaValue errorfunc;
/** Private constructor for main thread only */
public LuaThread(Globals globals) {
state = new State(globals, this, null);
state.status = STATUS_RUNNING;
this.globals = globals;
}
/**
* Create a LuaThread around a function and environment
* @param func The function to execute
*/
public LuaThread(Globals globals, LuaValue func) {
LuaValue.assert_(func != null, "function cannot be null");
state = new State(globals, this, func);
this.globals = globals;
}
public int type() {
return LuaValue.TTHREAD;
}
public String typename() {
return "thread";
}
public boolean isthread() {
return true;
}
public LuaThread optthread(LuaThread defval) {
return this;
}
public LuaThread checkthread() {
return this;
}
public LuaValue getmetatable() {
return s_metatable;
}
public String getStatus() {
return STATUS_NAMES[state.status];
}
public boolean isMainThread() {
return this.state.function == null;
}
public Varargs resume(Varargs args) {
final LuaThread.State s = this.state;
if (s.status > LuaThread.STATUS_SUSPENDED)
return LuaValue.varargsOf(LuaValue.FALSE,
LuaValue.valueOf("cannot resume "+(s.status==LuaThread.STATUS_DEAD? "dead": "non-suspended")+" coroutine"));
return s.lua_resume(this, args);
}
public static class State implements Runnable {
private final Globals globals;
final WeakReference lua_thread;
public final LuaValue function;
Varargs args = LuaValue.NONE;
Varargs result = LuaValue.NONE;
String error = null;
/** Hook function control state used by debug lib. */
public LuaValue hookfunc;
public boolean hookline;
public boolean hookcall;
public boolean hookrtrn;
public int hookcount;
public boolean inhook;
public int lastline;
public int bytecodes;
public int status = LuaThread.STATUS_INITIAL;
private Lock locker = new ReentrantLock();
private Condition cond = locker.newCondition();
State(Globals globals, LuaThread lua_thread, LuaValue function) {
this.globals = globals;
this.lua_thread = new WeakReference(lua_thread);
this.function = function;
}
public void run() {
locker.lock();
try {
try {
Varargs a = this.args;
this.args = LuaValue.NONE;
this.result = function.invoke(a);
} catch (Throwable t) {
this.error = t.getMessage();
} finally {
this.status = LuaThread.STATUS_DEAD;
cond.signal();
}
} finally {
locker.unlock();
}
}
public Varargs lua_resume(LuaThread new_thread, Varargs args) {
locker.lock();
try {
LuaThread previous_thread = globals.running;
try {
globals.running = new_thread;
this.args = args;
if (this.status == STATUS_INITIAL) {
this.status = STATUS_RUNNING;
Thread t = null;
if(SUPPORT_VIRTUAL_THREAD) {
LuaValue setting = globals.get(USE_PLATFORM_THREAD);
if(setting.isnil()) {//default
if(Thread.currentThread().isVirtual()) {
t = Thread.ofVirtual().name("Coroutine-"+(++coroutine_count)).start(this);
}
} else {
if(!setting.toboolean()) {
t = Thread.ofVirtual().name("Coroutine-"+(++coroutine_count)).start(this);
}
}
}
if (t == null){
new Thread(this, "Coroutine-"+(++coroutine_count)).start();
}
} else {
cond.signal();
}
if (previous_thread != null)
previous_thread.state.status = STATUS_NORMAL;
this.status = STATUS_RUNNING;
cond.await();
return (this.error != null?
LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf(this.error)):
LuaValue.varargsOf(LuaValue.TRUE, this.result));
} catch (InterruptedException ie) {
throw new OrphanedThread();
} finally {
this.args = LuaValue.NONE;
this.result = LuaValue.NONE;
this.error = null;
globals.running = previous_thread;
if (previous_thread != null)
globals.running.state.status =STATUS_RUNNING;
}
} finally {
locker.unlock();
}
}
public Varargs lua_yield(Varargs args) {
locker.lock();
try {
try {
this.result = args;
this.status = STATUS_SUSPENDED;
cond.signal();
do {
cond.await(thread_orphan_check_interval,TimeUnit.MILLISECONDS);
if (this.lua_thread.get() == null) {
this.status = STATUS_DEAD;
throw new OrphanedThread();
}
} while (this.status == STATUS_SUSPENDED);
return this.args;
} catch (InterruptedException ie) {
this.status = STATUS_DEAD;
throw new OrphanedThread();
} finally {
this.args = LuaValue.NONE;
this.result = LuaValue.NONE;
}
} finally {
locker.unlock();
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -21,8 +21,6 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2; package org.luaj.vm2;
import org.luaj.vm2.Varargs;
/** /**
* Base class for all concrete lua type values. * Base class for all concrete lua type values.
* <p> * <p>
@@ -77,7 +75,7 @@ import org.luaj.vm2.Varargs;
* } </pre> * } </pre>
* For this to work the file must be in the current directory, or in the class path, * For this to work the file must be in the current directory, or in the class path,
* dependening on the platform. * dependening on the platform.
* See {@link org.luaj.vm2.lib.jse.JsePlatform} and {@link org.luaj.vm2.lib.jme.JmePlatform} for details. * See {@link org.luaj.vm2.libs.jse.JsePlatform} and {@link org.luaj.vm2.libs.jme.JmePlatform} for details.
* <p> * <p>
* In general a {@link LuaError} may be thrown on any operation when the * In general a {@link LuaError} may be thrown on any operation when the
* types supplied to any operation are illegal from a lua perspective. * types supplied to any operation are illegal from a lua perspective.
@@ -101,10 +99,10 @@ import org.luaj.vm2.Varargs;
* {@link #INDEX}, {@link #NEWINDEX}, {@link #CALL}, {@link #MODE}, {@link #METATABLE}, * {@link #INDEX}, {@link #NEWINDEX}, {@link #CALL}, {@link #MODE}, {@link #METATABLE},
* {@link #ADD}, {@link #SUB}, {@link #DIV}, {@link #MUL}, {@link #POW}, * {@link #ADD}, {@link #SUB}, {@link #DIV}, {@link #MUL}, {@link #POW},
* {@link #MOD}, {@link #UNM}, {@link #LEN}, {@link #EQ}, {@link #LT}, * {@link #MOD}, {@link #UNM}, {@link #LEN}, {@link #EQ}, {@link #LT},
* {@link #LE}, {@link #TOSTRING}, and {@link #CONCAT}. * {@link #LE}, {@link #TOSTRING}, {@link #CONCAT}, {@link #PAIRS}, and {@link #IPAIRS}.
* *
* @see org.luaj.vm2.lib.jse.JsePlatform * @see org.luaj.vm2.libs.jse.JsePlatform
* @see org.luaj.vm2.lib.jme.JmePlatform * @see org.luaj.vm2.libs.jme.JmePlatform
* @see LoadState * @see LoadState
* @see Varargs * @see Varargs
*/ */
@@ -215,6 +213,27 @@ public class LuaValue extends Varargs {
/** LuaString constant with value "__div" for use as metatag */ /** LuaString constant with value "__div" for use as metatag */
public static final LuaString DIV = valueOf("__div"); public static final LuaString DIV = valueOf("__div");
/** LuaString constant with value "__idiv" for use as metatag */
public static final LuaString IDIV = valueOf("__idiv");
/** LuaString constant with value "__band" for use as metatag */
public static final LuaString BAND = valueOf("__band");
/** LuaString constant with value "__bor" for use as metatag */
public static final LuaString BOR = valueOf("__bor");
/** LuaString constant with value "__bxor" for use as metatag */
public static final LuaString BXOR = valueOf("__bxor");
/** LuaString constant with value "__shl" for use as metatag */
public static final LuaString SHL = valueOf("__shl");
/** LuaString constant with value "__shr" for use as metatag */
public static final LuaString SHR = valueOf("__shr");
/** LuaString constant with value "__bnot" for use as metatag */
public static final LuaString BNOT = valueOf("__bnot");
/** LuaString constant with value "__mul" for use as metatag */ /** LuaString constant with value "__mul" for use as metatag */
public static final LuaString MUL = valueOf("__mul"); public static final LuaString MUL = valueOf("__mul");
@@ -245,6 +264,12 @@ public class LuaValue extends Varargs {
/** LuaString constant with value "__concat" for use as metatag */ /** LuaString constant with value "__concat" for use as metatag */
public static final LuaString CONCAT = valueOf("__concat"); public static final LuaString CONCAT = valueOf("__concat");
/** LuaString constant with value "__pairs" for use as metatag */
public static final LuaString PAIRS = valueOf("__pairs");
/** LuaString constant with value "__ipairs" for use as metatag */
public static final LuaString IPAIRS = valueOf("__ipairs");
/** LuaString constant with value "" */ /** LuaString constant with value "" */
public static final LuaString EMPTYSTRING = valueOf(""); public static final LuaString EMPTYSTRING = valueOf("");
@@ -643,7 +668,7 @@ public class LuaValue extends Varargs {
* @see #isnumber() * @see #isnumber()
* @see #TNUMBER * @see #TNUMBER
*/ */
public double optdouble(double defval) { argerror("double"); return 0; } public double optdouble(double defval) { argerror("number"); return 0; }
/** Check that optional argument is a function and return as {@link LuaFunction} /** Check that optional argument is a function and return as {@link LuaFunction}
* <p> * <p>
@@ -855,7 +880,7 @@ public class LuaValue extends Varargs {
* @see #optdouble(double) * @see #optdouble(double)
* @see #TNUMBER * @see #TNUMBER
*/ */
public double checkdouble() { argerror("double"); return 0; } public double checkdouble() { argerror("number"); return 0; }
/** Check that the value is a function , or throw {@link LuaError} if not /** Check that the value is a function , or throw {@link LuaError} if not
* <p> * <p>
@@ -2010,6 +2035,13 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue neg() { return checkmetatag(UNM, "attempt to perform arithmetic on ").call(this); } public LuaValue neg() { return checkmetatag(UNM, "attempt to perform arithmetic on ").call(this); }
/** Unary bitwise not: return bitwise inverse value {@code (~this)}.
* @return numeric inverse as {@link LuaNumber} if integer-coercible,
* or metatag processing result if {@link #BNOT} metatag is defined
* @throws LuaError if {@code this} cannot be represented as an integer
*/
public LuaValue bnot() { return checkmetatag(BNOT, "attempt to perform bitwise operation on ").call(this); }
/** Length operator: return lua length of object {@code (#this)} including metatag processing as java int /** Length operator: return lua length of object {@code (#this)} including metatag processing as java int
* @return length as defined by the lua # operator * @return length as defined by the lua # operator
* or metatag processing result * or metatag processing result
@@ -2045,7 +2077,7 @@ public class LuaValue extends Varargs {
* @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue) * @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue)
* @see #EQ * @see #EQ
*/ */
public LuaValue eq( LuaValue val ) { return this == val? TRUE: FALSE; } public LuaValue eq( LuaValue val ) { return eq_b(val)? TRUE: FALSE; }
/** Equals: Perform equality comparison with another value /** Equals: Perform equality comparison with another value
* including metatag processing using {@link #EQ}, * including metatag processing using {@link #EQ},
@@ -2140,6 +2172,15 @@ public class LuaValue extends Varargs {
*/ */
public boolean raweq( int val ) { return false; } public boolean raweq( int val ) { return false; }
/** Equals: Perform direct equality comparison with a long value
* without metatag processing.
* @param val The long value to compare with.
* @return true if {@code this} is a {@link LuaNumber}
* whose value equals val,
* otherwise false
*/
public boolean raweq( long val ) { return false; }
/** Perform equality testing metatag processing /** Perform equality testing metatag processing
* @param lhs left-hand-side of equality expression * @param lhs left-hand-side of equality expression
* @param lhsmt metatag value for left-hand-side * @param lhsmt metatag value for left-hand-side
@@ -2401,6 +2442,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue div( LuaValue rhs ) { return arithmt(DIV,rhs); } public LuaValue div( LuaValue rhs ) { return arithmt(DIV,rhs); }
public LuaValue idiv( LuaValue rhs ) { return arithmt(IDIV,rhs); }
public LuaValue band( LuaValue rhs ) { return arithmt(BAND,rhs); }
public LuaValue bor( LuaValue rhs ) { return arithmt(BOR,rhs); }
public LuaValue bxor( LuaValue rhs ) { return arithmt(BXOR,rhs); }
public LuaValue shl( LuaValue rhs ) { return arithmt(SHL,rhs); }
public LuaValue shr( LuaValue rhs ) { return arithmt(SHR,rhs); }
/** Divide: Perform numeric divide operation by another value /** Divide: Perform numeric divide operation by another value
* of double type without metatag processing * of double type without metatag processing
* <p> * <p>
@@ -2416,6 +2469,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue div( double rhs ) { return aritherror("div"); } public LuaValue div( double rhs ) { return aritherror("div"); }
public LuaValue idiv( double rhs ) { return aritherror("idiv"); }
public LuaValue band( double rhs ) { return aritherror("band"); }
public LuaValue bor( double rhs ) { return aritherror("bor"); }
public LuaValue bxor( double rhs ) { return aritherror("bxor"); }
public LuaValue shl( double rhs ) { return aritherror("shl"); }
public LuaValue shr( double rhs ) { return aritherror("shr"); }
/** Divide: Perform numeric divide operation by another value /** Divide: Perform numeric divide operation by another value
* of int type without metatag processing * of int type without metatag processing
* <p> * <p>
@@ -2431,6 +2496,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue div( int rhs ) { return aritherror("div"); } public LuaValue div( int rhs ) { return aritherror("div"); }
public LuaValue idiv( int rhs ) { return aritherror("idiv"); }
public LuaValue band( int rhs ) { return aritherror("band"); }
public LuaValue bor( int rhs ) { return aritherror("bor"); }
public LuaValue bxor( int rhs ) { return aritherror("bxor"); }
public LuaValue shl( int rhs ) { return aritherror("shl"); }
public LuaValue shr( int rhs ) { return aritherror("shr"); }
/** Reverse-divide: Perform numeric divide operation into another value /** Reverse-divide: Perform numeric divide operation into another value
* with metatag processing * with metatag processing
* <p> * <p>
@@ -2446,6 +2523,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue divInto(double lhs) { return arithmtwith(DIV,lhs); } public LuaValue divInto(double lhs) { return arithmtwith(DIV,lhs); }
public LuaValue idivInto(double lhs) { return arithmtwith(IDIV,lhs); }
public LuaValue bandInto(double lhs) { return arithmtwith(BAND,lhs); }
public LuaValue borInto(double lhs) { return arithmtwith(BOR,lhs); }
public LuaValue bxorInto(double lhs) { return arithmtwith(BXOR,lhs); }
public LuaValue shlInto(double lhs) { return arithmtwith(SHL,lhs); }
public LuaValue shrInto(double lhs) { return arithmtwith(SHR,lhs); }
/** Modulo: Perform numeric modulo operation with another value /** Modulo: Perform numeric modulo operation with another value
* of unknown type, * of unknown type,
* including metatag processing. * including metatag processing.
@@ -3143,7 +3232,7 @@ public class LuaValue extends Varargs {
* @return {@link LuaString} corresponding to the value if a string or number * @return {@link LuaString} corresponding to the value if a string or number
* @throws LuaError if not a string or number * @throws LuaError if not a string or number
*/ */
public LuaString strvalue() { typerror("strValue"); return null; } public LuaString strvalue() { typerror("string or number"); return null; }
/** Return this value as a strong reference, or null if it was weak and is no longer referenced. /** Return this value as a strong reference, or null if it was weak and is no longer referenced.
* @return {@link LuaValue} referred to, or null if it was weak and is no longer referenced. * @return {@link LuaValue} referred to, or null if it was weak and is no longer referenced.
@@ -3165,6 +3254,13 @@ public class LuaValue extends Varargs {
*/ */
public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); } public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); }
/** Convert java long to a {@link LuaValue}.
*
* @param l long value to convert
* @return {@link LuaInteger} instance, possibly pooled, whose value is l
*/
public static LuaInteger valueOf(long l) { return LuaInteger.valueOf(l); }
/** Convert java double to a {@link LuaValue}. /** Convert java double to a {@link LuaValue}.
* This may return a {@link LuaInteger} or {@link LuaDouble} depending * This may return a {@link LuaInteger} or {@link LuaDouble} depending
* on the value supplied. * on the value supplied.
@@ -3298,7 +3394,7 @@ public class LuaValue extends Varargs {
if ((!res.isnil()) || (tm = t.metatag(INDEX)).isnil()) if ((!res.isnil()) || (tm = t.metatag(INDEX)).isnil())
return res; return res;
} else if ((tm = t.metatag(INDEX)).isnil()) } else if ((tm = t.metatag(INDEX)).isnil())
t.indexerror(); t.indexerror(key.tojstring());
if (tm.isfunction()) if (tm.isfunction())
return tm.call(t, key); return tm.call(t, key);
t = tm; t = tm;
@@ -3326,7 +3422,7 @@ public class LuaValue extends Varargs {
return true; return true;
} }
} else if ((tm = t.metatag(NEWINDEX)).isnil()) } else if ((tm = t.metatag(NEWINDEX)).isnil())
t.typerror("index"); throw new LuaError("table expected for set index ('" + key + "') value, got " + t.typename());
if (tm.isfunction()) { if (tm.isfunction()) {
tm.call(t, key, value); tm.call(t, key, value);
return true; return true;
@@ -3362,7 +3458,7 @@ public class LuaValue extends Varargs {
protected LuaValue checkmetatag(LuaValue tag, String reason) { protected LuaValue checkmetatag(LuaValue tag, String reason) {
LuaValue h = this.metatag(tag); LuaValue h = this.metatag(tag);
if ( h.isnil() ) if ( h.isnil() )
throw new LuaError(reason+typename()); throw new LuaError(reason + "a " + typename() + " value");
return h; return h;
} }
@@ -3389,8 +3485,8 @@ public class LuaValue extends Varargs {
/** Throw {@link LuaError} indicating index was attempted on illegal type /** Throw {@link LuaError} indicating index was attempted on illegal type
* @throws LuaError when called. * @throws LuaError when called.
*/ */
private void indexerror() { private void indexerror(String key) {
error( "attempt to index ? (a "+typename()+" value)" ); error( "attempt to index ? (a "+typename()+" value) with key '" + key + "'" );
} }
/** Construct a {@link Varargs} around an array of {@link LuaValue}s. /** Construct a {@link Varargs} around an array of {@link LuaValue}s.
@@ -3404,8 +3500,8 @@ public class LuaValue extends Varargs {
switch ( v.length ) { switch ( v.length ) {
case 0: return NONE; case 0: return NONE;
case 1: return v[0]; case 1: return v[0];
case 2: return new Varargs.PairVarargs(v[0],v[1]); case 2: return new PairVarargs(v[0],v[1]);
default: return new Varargs.ArrayVarargs(v,NONE); default: return new ArrayVarargs(v,NONE);
} }
} }
@@ -3421,12 +3517,12 @@ public class LuaValue extends Varargs {
switch ( v.length ) { switch ( v.length ) {
case 0: return r; case 0: return r;
case 1: return r.narg()>0? case 1: return r.narg()>0?
(Varargs) new Varargs.PairVarargs(v[0],r): (Varargs) new PairVarargs(v[0],r):
(Varargs) v[0]; (Varargs) v[0];
case 2: return r.narg()>0? case 2: return r.narg()>0?
(Varargs) new Varargs.ArrayVarargs(v,r): (Varargs) new ArrayVarargs(v,r):
(Varargs) new Varargs.PairVarargs(v[0],v[1]); (Varargs) new PairVarargs(v[0],v[1]);
default: return new Varargs.ArrayVarargs(v,r); default: return new ArrayVarargs(v,r);
} }
} }
@@ -3443,8 +3539,8 @@ public class LuaValue extends Varargs {
switch ( length ) { switch ( length ) {
case 0: return NONE; case 0: return NONE;
case 1: return v[offset]; case 1: return v[offset];
case 2: return new Varargs.PairVarargs(v[offset+0],v[offset+1]); case 2: return new PairVarargs(v[offset+0],v[offset+1]);
default: return new Varargs.ArrayPartVarargs(v, offset, length, NONE); default: return new ArrayPartVarargs(v, offset, length, NONE);
} }
} }
@@ -3465,12 +3561,12 @@ public class LuaValue extends Varargs {
switch ( length ) { switch ( length ) {
case 0: return more; case 0: return more;
case 1: return more.narg()>0? case 1: return more.narg()>0?
(Varargs) new Varargs.PairVarargs(v[offset],more): (Varargs) new PairVarargs(v[offset],more):
(Varargs) v[offset]; (Varargs) v[offset];
case 2: return more.narg()>0? case 2: return more.narg()>0?
(Varargs) new Varargs.ArrayPartVarargs(v,offset,length,more): (Varargs) new ArrayPartVarargs(v,offset,length,more):
(Varargs) new Varargs.PairVarargs(v[offset],v[offset+1]); (Varargs) new PairVarargs(v[offset],v[offset+1]);
default: return new Varargs.ArrayPartVarargs(v,offset,length,more); default: return new ArrayPartVarargs(v,offset,length,more);
} }
} }
@@ -3487,7 +3583,7 @@ public class LuaValue extends Varargs {
public static Varargs varargsOf(LuaValue v, Varargs r) { public static Varargs varargsOf(LuaValue v, Varargs r) {
switch ( r.narg() ) { switch ( r.narg() ) {
case 0: return v; case 0: return v;
default: return new Varargs.PairVarargs(v,r); default: return new PairVarargs(v,r);
} }
} }
@@ -3504,8 +3600,8 @@ public class LuaValue extends Varargs {
*/ */
public static Varargs varargsOf(LuaValue v1,LuaValue v2,Varargs v3) { public static Varargs varargsOf(LuaValue v1,LuaValue v2,Varargs v3) {
switch ( v3.narg() ) { switch ( v3.narg() ) {
case 0: return new Varargs.PairVarargs(v1,v2); case 0: return new PairVarargs(v1,v2);
default: return new Varargs.ArrayPartVarargs(new LuaValue[]{v1,v2}, 0, 2, v3); default: return new ArrayPartVarargs(new LuaValue[]{v1,v2}, 0, 2, v3);
} }
} }

Binary file not shown.

Binary file not shown.

View File

@@ -22,7 +22,7 @@
package org.luaj.vm2; package org.luaj.vm2;
/** /**
* {@link java.lang.Error} sublcass that indicates a lua thread that is no * {@link Error} sublcass that indicates a lua thread that is no
* longer referenced has been detected. * longer referenced has been detected.
* <p> * <p>
* The java thread in which this is thrown should correspond to a * The java thread in which this is thrown should correspond to a

Binary file not shown.

View File

@@ -128,6 +128,10 @@ public class Print extends Lua {
} }
static void printValue( PrintStream ps, LuaValue v ) { static void printValue( PrintStream ps, LuaValue v ) {
if (v == null) {
ps.print("null");
return;
}
switch ( v.type() ) { switch ( v.type() ) {
case LuaValue.TSTRING: printString( ps, (LuaString) v ); break; case LuaValue.TSTRING: printString( ps, (LuaString) v ); break;
default: ps.print( v.tojstring() ); default: ps.print( v.tojstring() );
@@ -136,7 +140,7 @@ public class Print extends Lua {
} }
static void printConstant(PrintStream ps, Prototype f, int i) { static void printConstant(PrintStream ps, Prototype f, int i) {
printValue( ps, f.k[i] ); printValue( ps, i < f.k.length ? f.k[i] : LuaValue.valueOf("UNKNOWN_CONST_" + i) );
} }
static void printUpvalue(PrintStream ps, Upvaldesc u) { static void printUpvalue(PrintStream ps, Upvaldesc u) {
@@ -152,7 +156,7 @@ public class Print extends Lua {
int[] code = f.code; int[] code = f.code;
int pc, n = code.length; int pc, n = code.length;
for (pc = 0; pc < n; pc++) { for (pc = 0; pc < n; pc++) {
printOpCode(f, pc); pc = printOpCode(f, pc);
ps.println(); ps.println();
} }
} }
@@ -161,9 +165,10 @@ public class Print extends Lua {
* Print an opcode in a prototype * Print an opcode in a prototype
* @param f the {@link Prototype} * @param f the {@link Prototype}
* @param pc the program counter to look up and print * @param pc the program counter to look up and print
* @return pc same as above or changed
*/ */
public static void printOpCode(Prototype f, int pc) { public static int printOpCode(Prototype f, int pc) {
printOpCode(ps,f,pc); return printOpCode(ps,f,pc);
} }
/** /**
@@ -171,8 +176,9 @@ public class Print extends Lua {
* @param ps the {@link PrintStream} to print to * @param ps the {@link PrintStream} to print to
* @param f the {@link Prototype} * @param f the {@link Prototype}
* @param pc the program counter to look up and print * @param pc the program counter to look up and print
* @return pc same as above or changed
*/ */
public static void printOpCode(PrintStream ps, Prototype f, int pc) { public static int printOpCode(PrintStream ps, Prototype f, int pc) {
int[] code = f.code; int[] code = f.code;
int i = code[pc]; int i = code[pc];
int o = GET_OPCODE(i); int o = GET_OPCODE(i);
@@ -187,6 +193,9 @@ public class Print extends Lua {
ps.print("[" + line + "] "); ps.print("[" + line + "] ");
else else
ps.print("[-] "); ps.print("[-] ");
if (o >= OPNAMES.length - 1) {
ps.print("UNKNOWN_OP_" + o + " ");
} else {
ps.print(OPNAMES[o] + " "); ps.print(OPNAMES[o] + " ");
switch (getOpMode(o)) { switch (getOpMode(o)) {
case iABC: case iABC:
@@ -218,11 +227,19 @@ public class Print extends Lua {
case OP_GETUPVAL: case OP_GETUPVAL:
case OP_SETUPVAL: case OP_SETUPVAL:
ps.print(" ; "); ps.print(" ; ");
if (b < f.upvalues.length) {
printUpvalue(ps, f.upvalues[b]); printUpvalue(ps, f.upvalues[b]);
} else {
ps.print("UNKNOWN_UPVALUE_" + b);
}
break; break;
case OP_GETTABUP: case OP_GETTABUP:
ps.print(" ; "); ps.print(" ; ");
if (b < f.upvalues.length) {
printUpvalue(ps, f.upvalues[b]); printUpvalue(ps, f.upvalues[b]);
} else {
ps.print("UNKNOWN_UPVALUE_" + b);
}
ps.print(" "); ps.print(" ");
if (ISK(c)) if (ISK(c))
printConstant(ps, f, INDEXK(c)); printConstant(ps, f, INDEXK(c));
@@ -231,7 +248,11 @@ public class Print extends Lua {
break; break;
case OP_SETTABUP: case OP_SETTABUP:
ps.print(" ; "); ps.print(" ; ");
if (a < f.upvalues.length) {
printUpvalue(ps, f.upvalues[a]); printUpvalue(ps, f.upvalues[a]);
} else {
ps.print("UNKNOWN_UPVALUE_" + a);
}
ps.print(" "); ps.print(" ");
if (ISK(b)) if (ISK(b))
printConstant(ps, f, INDEXK(b)); printConstant(ps, f, INDEXK(b));
@@ -255,6 +276,12 @@ public class Print extends Lua {
case OP_SUB: case OP_SUB:
case OP_MUL: case OP_MUL:
case OP_DIV: case OP_DIV:
case OP_IDIV:
case OP_BAND:
case OP_BOR:
case OP_BXOR:
case OP_SHL:
case OP_SHR:
case OP_POW: case OP_POW:
case OP_EQ: case OP_EQ:
case OP_LT: case OP_LT:
@@ -278,11 +305,15 @@ public class Print extends Lua {
ps.print(" ; to " + (sbx + pc + 2)); ps.print(" ; to " + (sbx + pc + 2));
break; break;
case OP_CLOSURE: case OP_CLOSURE:
if (bx < f.p.length) {
ps.print(" ; " + f.p[bx].getClass().getName()); ps.print(" ; " + f.p[bx].getClass().getName());
} else {
ps.print(" ; UNKNOWN_PROTYPE_" + bx);
}
break; break;
case OP_SETLIST: case OP_SETLIST:
if (c == 0) if (c == 0)
ps.print(" ; " + ((int) code[++pc])); ps.print(" ; " + ((int) code[++pc]) + " (stored in the next OP)");
else else
ps.print(" ; " + ((int) c)); ps.print(" ; " + ((int) c));
break; break;
@@ -293,6 +324,8 @@ public class Print extends Lua {
break; break;
} }
} }
return pc;
}
private static int getline(Prototype f, int pc) { private static int getline(Prototype f, int pc) {
return pc>0 && f.lineinfo!=null && pc<f.lineinfo.length? f.lineinfo[pc]: -1; return pc>0 && f.lineinfo!=null && pc<f.lineinfo.length? f.lineinfo[pc]: -1;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -291,7 +291,7 @@ public abstract class Varargs {
* @return java double value if argument i is a number or string that converts to a number * @return java double value if argument i is a number or string that converts to a number
* @exception LuaError if the argument is not a number * @exception LuaError if the argument is not a number
* */ * */
public double checkdouble(int i) { return arg(i).checknumber().todouble(); } public double checkdouble(int i) { return arg(i).checkdouble(); }
/** Return argument i as a function, or throw an error if an incompatible type. /** Return argument i as a function, or throw an error if an incompatible type.
* @param i the index of the argument to test, 1 is the first argument * @param i the index of the argument to test, 1 is the first argument
@@ -300,12 +300,12 @@ public abstract class Varargs {
* */ * */
public LuaFunction checkfunction(int i) { return arg(i).checkfunction(); } public LuaFunction checkfunction(int i) { return arg(i).checkfunction(); }
/** Return argument i as a java int value, discarding any fractional part, or throw an error if not a number. /** Return argument i as a java int value, or throw an error if it cannot be converted to one.
* @param i the index of the argument to test, 1 is the first argument * @param i the index of the argument to test, 1 is the first argument
* @return int value with fraction discarded and truncated if necessary if argument i is number * @return int value if argument i is a number or string that converts to a number
* @exception LuaError if the argument is not a number * @exception LuaError if the argument cannot be represented by a java int value
* */ * */
public int checkint(int i) { return arg(i).checknumber().toint(); } public int checkint(int i) { return arg(i).checkint(); }
/** Return argument i as a java int value, or throw an error if not a number or is not representable by a java int. /** Return argument i as a java int value, or throw an error if not a number or is not representable by a java int.
* @param i the index of the argument to test, 1 is the first argument * @param i the index of the argument to test, 1 is the first argument
@@ -314,12 +314,12 @@ public abstract class Varargs {
* */ * */
public LuaInteger checkinteger(int i) { return arg(i).checkinteger(); } public LuaInteger checkinteger(int i) { return arg(i).checkinteger(); }
/** Return argument i as a java long value, discarding any fractional part, or throw an error if not a number. /** Return argument i as a java long value, or throw an error if it cannot be converted to one.
* @param i the index of the argument to test, 1 is the first argument * @param i the index of the argument to test, 1 is the first argument
* @return long value with fraction discarded and truncated if necessary if argument i is number * @return long value if argument i is a number or string that converts to a number
* @exception LuaError if the argument is not a number * @exception LuaError if the argument cannot be represented by a java long value
* */ * */
public long checklong(int i) { return arg(i).checknumber().tolong(); } public long checklong(int i) { return arg(i).checklong(); }
/** Return argument i as a LuaNumber, or throw an error if not a number or string that can be converted to a number. /** Return argument i as a LuaNumber, or throw an error if not a number or string that can be converted to a number.
* @param i the index of the argument to test, 1 is the first argument * @param i the index of the argument to test, 1 is the first argument
@@ -537,7 +537,7 @@ public abstract class Varargs {
if (newstart == this.end) if (newstart == this.end)
return v.arg(this.end); return v.arg(this.end);
if (newstart == this.end-1) if (newstart == this.end-1)
return new Varargs.PairVarargs(v.arg(this.end-1), v.arg(this.end)); return new PairVarargs(v.arg(this.end-1), v.arg(this.end));
return new SubVarargs(v, newstart, this.end); return new SubVarargs(v, newstart, this.end);
} }
return new SubVarargs(v, newstart, this.end); return new SubVarargs(v, newstart, this.end);
@@ -707,8 +707,10 @@ public abstract class Varargs {
/** Return Varargs that cannot be using a shared array for the storage, and is flattened. /** Return Varargs that cannot be using a shared array for the storage, and is flattened.
* Internal utility method not intended to be called directly from user code. * Internal utility method not intended to be called directly from user code.
* @return Varargs containing same values, but flattened and with a new array if needed. * @return Varargs containing same values, but flattened and with a new array if needed.
* @exclude
* @hide
*/ */
Varargs dealias() { public Varargs dealias() {
int n = narg(); int n = narg();
switch (n) { switch (n) {
case 0: return LuaValue.NONE; case 0: return LuaValue.NONE;

Some files were not shown because too many files have changed in this diff Show More