117 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
613 changed files with 10138 additions and 10249 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,6 +1,12 @@
# This is a fork! # This is a fork!
<div style="border: 1px dotted red; margin: 1.em 0.5em; font-weight: bold; color: red;"> <div style="border: 1px dotted red; margin: 1.em 0.5em; font-weight: bold; color: red;">
This repository has been forked from the original CVS sources of Luaj. 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 The commit history has been converted to make sure that the original work of
James Roseborough and Ian Farmer is not lost. James Roseborough and Ian Farmer is not lost.
Unfortunately, I was not able to contact either James or Ian to hand over Unfortunately, I was not able to contact either James or Ian to hand over
@@ -12,16 +18,13 @@ on.<br>
-- Benjamin P. Jung, Jan. 26th 2018 -- Benjamin P. Jung, Jan. 26th 2018
</div> </div>
<h1>Getting Started with LuaJ</h1>
<h1>Getting Started with LuaJ</h1> <h1>Getting Started with LuaJ</h1>
James Roseborough, Ian Farmer, Version 3.0.2 James Roseborough, Ian Farmer, Version 3.0.2
<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>
@@ -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.2.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.2.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.2.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.2.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.2.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.2.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.2.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.2.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.2.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.2.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.2.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.2.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.2.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 {
@@ -886,10 +883,6 @@ Unit test scripts can be found in these locations
<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>
@@ -1031,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()
@@ -1039,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

@@ -31,10 +31,10 @@ import java.io.InputStream;
* <p> * <p>
* The {@link LoadState} class provides the default {@link Globals.Undumper} * The {@link LoadState} class provides the default {@link Globals.Undumper}
* which is used to undump a string of bytes that represent a lua binary file * which is used to undump a string of bytes that represent a lua binary file
* using either the C-based lua compiler, or luaj's * using either the C-based lua compiler, or luaj's
* {@link org.luaj.vm2.compiler.LuaC} compiler. * {@link org.luaj.vm2.compiler.LuaC} compiler.
* <p> * <p>
* The canonical method to load and execute code is done * The canonical method to load and execute code is done
* indirectly using the Globals: * indirectly using the Globals:
* <pre> {@code * <pre> {@code
* Globals globals = JsePlatform.standardGlobals(); * Globals globals = JsePlatform.standardGlobals();
@@ -44,10 +44,10 @@ 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>
* *
* A lua binary file is created via the {@link org.luaj.vm2.compiler.DumpState} class * A lua binary file is created via the {@link org.luaj.vm2.compiler.DumpState} class
@@ -60,7 +60,7 @@ import java.io.InputStream;
* byte[] lua_binary_file_bytes = o.toByteArray(); * byte[] lua_binary_file_bytes = o.toByteArray();
* } </pre> * } </pre>
* *
* The {@link LoadState}'s default undumper {@link #instance} * The {@link LoadState}'s default undumper {@link #instance}
* may be used directly to undump these bytes: * may be used directly to undump these bytes:
* <pre> {@code * <pre> {@code
* Prototypep = LoadState.instance.undump(new ByteArrayInputStream(lua_binary_file_bytes), "main.lua"); * Prototypep = LoadState.instance.undump(new ByteArrayInputStream(lua_binary_file_bytes), "main.lua");
@@ -99,7 +99,7 @@ public class LoadState {
/** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */ /** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */
public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4; public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4;
// type constants // type constants
public static final int LUA_TINT = (-2); public static final int LUA_TINT = (-2);
public static final int LUA_TNONE = (-1); public static final int LUA_TNONE = (-1);
public static final int LUA_TNIL = 0; public static final int LUA_TNIL = 0;
@@ -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 = {};
@@ -168,17 +167,17 @@ public class LoadState {
} }
/** Load a 4-byte int value from the input stream /** Load a 4-byte int value from the input stream
* @return the int value laoded. * @return the int value laoded.
**/ **/
int loadInt() throws IOException { int loadInt() throws IOException {
is.readFully(buf,0,4); is.readFully(buf,0,4);
return luacLittleEndian? return luacLittleEndian?
(buf[3] << 24) | ((0xff & buf[2]) << 16) | ((0xff & buf[1]) << 8) | (0xff & buf[0]): (buf[3] << 24) | ((0xff & buf[2]) << 16) | ((0xff & buf[1]) << 8) | (0xff & buf[0]):
(buf[0] << 24) | ((0xff & buf[1]) << 16) | ((0xff & buf[2]) << 8) | (0xff & buf[3]); (buf[0] << 24) | ((0xff & buf[1]) << 16) | ((0xff & buf[2]) << 8) | (0xff & buf[3]);
} }
/** Load an array of int values from the input stream /** Load an array of int values from the input stream
* @return the array of int values laoded. * @return the array of int values laoded.
**/ **/
int[] loadIntArray() throws IOException { int[] loadIntArray() throws IOException {
int n = loadInt(); int n = loadInt();
@@ -192,7 +191,7 @@ public class LoadState {
is.readFully(buf,0,m); is.readFully(buf,0,m);
int[] array = new int[n]; int[] array = new int[n];
for ( int i=0, j=0; i<n; ++i, j+=4 ) for ( int i=0, j=0; i<n; ++i, j+=4 )
array[i] = luacLittleEndian? array[i] = luacLittleEndian?
(buf[j+3] << 24) | ((0xff & buf[j+2]) << 16) | ((0xff & buf[j+1]) << 8) | (0xff & buf[j+0]): (buf[j+3] << 24) | ((0xff & buf[j+2]) << 16) | ((0xff & buf[j+1]) << 8) | (0xff & buf[j+0]):
(buf[j+0] << 24) | ((0xff & buf[j+1]) << 16) | ((0xff & buf[j+2]) << 8) | (0xff & buf[j+3]); (buf[j+0] << 24) | ((0xff & buf[j+1]) << 16) | ((0xff & buf[j+2]) << 8) | (0xff & buf[j+3]);
@@ -200,7 +199,7 @@ public class LoadState {
} }
/** Load a long value from the input stream /** Load a long value from the input stream
* @return the long value laoded. * @return the long value laoded.
**/ **/
long loadInt64() throws IOException { long loadInt64() throws IOException {
int a,b; int a,b;
@@ -215,7 +214,7 @@ public class LoadState {
} }
/** Load a lua strin gvalue from the input stream /** Load a lua strin gvalue from the input stream
* @return the {@link LuaString} value laoded. * @return the {@link LuaString} value laoded.
**/ **/
LuaString loadString() throws IOException { LuaString loadString() throws IOException {
int size = this.luacSizeofSizeT == 8? (int) loadInt64(): loadInt(); int size = this.luacSizeofSizeT == 8? (int) loadInt64(): loadInt();
@@ -227,7 +226,7 @@ public class LoadState {
} }
/** /**
* Convert bits in a long value to a {@link LuaValue}. * Convert bits in a long value to a {@link LuaValue}.
* @param bits long value containing the bits * @param bits long value containing the bits
* @return {@link LuaInteger} or {@link LuaDouble} whose value corresponds to the bits provided. * @return {@link LuaInteger} or {@link LuaDouble} whose value corresponds to the bits provided.
*/ */
@@ -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 );
} }
} }
@@ -251,7 +250,7 @@ public class LoadState {
return LuaValue.valueOf( Double.longBitsToDouble(bits) ); return LuaValue.valueOf( Double.longBitsToDouble(bits) );
} }
/** /**
* Load a number from a binary chunk * Load a number from a binary chunk
* @return the {@link LuaValue} loaded * @return the {@link LuaValue} loaded
* @throws IOException if an i/o exception occurs * @throws IOException if an i/o exception occurs
@@ -335,7 +334,7 @@ public class LoadState {
f.upvalues[i].name = loadString(); f.upvalues[i].name = loadString();
} }
/** /**
* Load a function prototype from the input stream * Load a function prototype from the input stream
* @param p name of the source * @param p name of the source
* @return {@link Prototype} instance that was loaded * @return {@link Prototype} instance that was loaded
@@ -366,8 +365,8 @@ public class LoadState {
} }
/** /**
* Load the lua chunk header values. * Load the lua chunk header values.
* @throws IOException if an i/o exception occurs. * @throws IOException if an i/o exception occurs.
*/ */
public void loadHeader() throws IOException { public void loadHeader() throws IOException {
luacVersion = is.readByte(); luacVersion = is.readByte();
@@ -392,7 +391,7 @@ public class LoadState {
*/ */
public static Prototype undump(InputStream stream, String chunkname) throws IOException { public static Prototype undump(InputStream stream, String chunkname) throws IOException {
// check rest of signature // check rest of signature
if ( stream.read() != LUA_SIGNATURE[0] if ( stream.read() != LUA_SIGNATURE[0]
|| stream.read() != LUA_SIGNATURE[1] || stream.read() != LUA_SIGNATURE[1]
|| stream.read() != LUA_SIGNATURE[2] || stream.read() != LUA_SIGNATURE[2]
|| stream.read() != LUA_SIGNATURE[3] ) || stream.read() != LUA_SIGNATURE[3] )

Binary file not shown.

Binary file not shown.

View File

@@ -23,14 +23,14 @@ package org.luaj.vm2;
/** /**
* Constants for lua limits and opcodes. * Constants for lua limits and opcodes.
* <p> * <p>
* This is a direct translation of C lua distribution header file constants * This is a direct translation of C lua distribution header file constants
* for bytecode creation and processing. * for bytecode creation and processing.
*/ */
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);
@@ -89,17 +88,18 @@ public class Lua {
public static final int MAXARG_sBx = (MAXARG_Bx>>1); /* `sBx' is signed */ public static final int MAXARG_sBx = (MAXARG_Bx>>1); /* `sBx' is signed */
public static final int MAXARG_Ax = ((1<<SIZE_Ax)-1); public static final int MAXARG_Ax = ((1<<SIZE_Ax)-1);
public static final int MASK_OP = ((1<<SIZE_OP)-1)<<POS_OP; public static final int MASK_OP = ((1<<SIZE_OP)-1)<<POS_OP;
public static final int MASK_A = ((1<<SIZE_A)-1)<<POS_A; public static final int MASK_A = ((1<<SIZE_A)-1)<<POS_A;
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;
public static final int MASK_NOT_B = ~MASK_B; public static final int MASK_NOT_B = ~MASK_B;
public static final int MASK_NOT_C = ~MASK_C; public static final int MASK_NOT_C = ~MASK_C;
public static final int MASK_NOT_Bx = ~MASK_Bx; public static final int MASK_NOT_Bx = ~MASK_Bx;
/* /*
** the following macros help to manipulate instructions ** the following macros help to manipulate instructions
@@ -200,48 +200,55 @@ 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;
/* pseudo-opcodes used in parsing only. */ /* pseudo-opcodes used in parsing only. */
public static final int OP_GT = 63; // > public static final int OP_GT = 63; // >
public static final int OP_GE = 62; // >= public static final int OP_GE = 62; // >=
public static final int OP_NEQ = 61; // ~= public static final int OP_NEQ = 61; // ~=
public static final int OP_AND = 60; // and public static final int OP_AND = 60; // and
public static final int OP_OR = 59; // or public static final int OP_OR = 59; // or
/*=========================================================================== /*===========================================================================
Notes: Notes:
@@ -271,7 +278,7 @@ public class Lua {
** bits 4-5: B arg mode ** bits 4-5: B arg mode
** bit 6: instruction set register A ** bit 6: instruction set register A
** bit 7: operator is a test ** bit 7: operator is a test
*/ */
public static final int OpArgN = 0; /* argument is not used */ public static final int OpArgN = 0; /* argument is not used */
public static final int OpArgU = 1; /* argument is used */ public static final int OpArgU = 1; /* argument is used */
@@ -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 */
@@ -353,7 +367,7 @@ public class Lua {
source = "[string \""+source; source = "[string \""+source;
end = "\"]"; end = "\"]";
} }
int n = source.length() + end.length(); int n = source.length() + end.length();
if ( n > MAXSRC ) if ( n > MAXSRC )
source = source.substring(0,MAXSRC-end.length()-3) + "..."; source = source.substring(0,MAXSRC-end.length()-3) + "...";
return source + end; return source + end;

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,21 +21,21 @@
******************************************************************************/ ******************************************************************************/
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.
* <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)}
* functions. This ensures that values which can be represented as int * functions. This ensures that values which can be represented as int
* are wrapped in {@link LuaInteger} instead of {@link LuaDouble}. * are wrapped in {@link LuaInteger} instead of {@link LuaDouble}.
* <p> * <p>
* Almost all API's implemented in LuaDouble are defined and documented in {@link LuaValue}. * Almost all API's implemented in LuaDouble are defined and documented in {@link LuaValue}.
* <p> * <p>
* However the constants {@link #NAN}, {@link #POSINF}, {@link #NEGINF}, * However the constants {@link #NAN}, {@link #POSINF}, {@link #NEGINF},
* {@link #JSTR_NAN}, {@link #JSTR_POSINF}, and {@link #JSTR_NEGINF} may be useful * {@link #JSTR_NAN}, {@link #JSTR_POSINF}, and {@link #JSTR_NEGINF} may be useful
* when dealing with Nan or Infinite values. * when dealing with Nan or Infinite values.
* <p> * <p>
* LuaDouble also defines functions for handling the unique math rules of lua devision and modulo in * LuaDouble also defines functions for handling the unique math rules of lua devision and modulo in
* <ul> * <ul>
@@ -43,7 +43,7 @@ import org.luaj.vm2.lib.MathLib;
* <li>{@link #ddiv_d(double, double)}</li> * <li>{@link #ddiv_d(double, double)}</li>
* <li>{@link #dmod(double, double)}</li> * <li>{@link #dmod(double, double)}</li>
* <li>{@link #dmod_d(double, double)}</li> * <li>{@link #dmod_d(double, double)}</li>
* </ul> * </ul>
* <p> * <p>
* @see LuaValue * @see LuaValue
* @see LuaNumber * @see LuaNumber
@@ -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 */
@@ -90,7 +95,7 @@ public class LuaDouble extends LuaNumber {
} }
public boolean islong() { public boolean islong() {
return v == (long) v; return v == (long) v;
} }
public byte tobyte() { return (byte) (long) v; } public byte tobyte() { return (byte) (long) v; }
@@ -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); }
@@ -151,12 +167,16 @@ public class LuaDouble extends LuaNumber {
/** Divide two double numbers according to lua math, and return a {@link LuaValue} result. /** Divide two double numbers according to lua math, and return a {@link LuaValue} 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.
* @return {@link LuaValue} for the result of the division, * @return {@link LuaValue} for the result of the division,
* taking into account positive and negiative infinity, and Nan * taking into account positive and negiative infinity, and Nan
* @see #ddiv_d(double, double) * @see #ddiv_d(double, double)
*/ */
public static LuaValue ddiv(double lhs, double rhs) { public static LuaValue ddiv(double lhs, double rhs) {
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.
@@ -166,15 +186,15 @@ public class LuaDouble extends LuaNumber {
* @see #ddiv(double, double) * @see #ddiv(double, double)
*/ */
public static double ddiv_d(double lhs, double rhs) { public static double ddiv_d(double lhs, double rhs) {
return rhs!=0? lhs / rhs: lhs>0? Double.POSITIVE_INFINITY: lhs==0? Double.NaN: Double.NEGATIVE_INFINITY; return rhs!=0? lhs / rhs: lhs>0? Double.POSITIVE_INFINITY: lhs==0? Double.NaN: Double.NEGATIVE_INFINITY;
} }
/** Take modulo double numbers according to lua math, and return a {@link LuaValue} result. /** Take modulo double numbers according to lua math, and return a {@link LuaValue} result.
* @param lhs Left-hand-side of the modulo. * @param lhs Left-hand-side of the modulo.
* @param rhs Right-hand-side of the modulo. * @param rhs Right-hand-side of the modulo.
* @return {@link LuaValue} for the result of the modulo, * @return {@link LuaValue} for the result of the modulo,
* using lua's rules for modulo * using lua's rules for modulo
* @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) {
if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return NAN; if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return NAN;
@@ -190,7 +210,7 @@ public class LuaDouble extends LuaNumber {
/** 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.
* @param lhs Left-hand-side of the modulo. * @param lhs Left-hand-side of the modulo.
* @param rhs Right-hand-side of the modulo. * @param rhs Right-hand-side of the modulo.
* @return double value for the result of the modulo, * @return double value for the result of the modulo,
* using lua's rules for modulo * using lua's rules for modulo
* @see #dmod(double, double) * @see #dmod(double, double)
*/ */
@@ -206,28 +226,28 @@ public class LuaDouble extends LuaNumber {
} }
// 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; }
@@ -236,17 +256,17 @@ public class LuaDouble extends LuaNumber {
public String tojstring() { public String tojstring() {
/* /*
if ( v == 0.0 ) { // never occurs in J2me if ( v == 0.0 ) { // never occurs in J2me
long bits = Double.doubleToLongBits( v ); long bits = Double.doubleToLongBits( v );
return ( bits >> 63 == 0 ) ? "0" : "-0"; return ( bits >> 63 == 0 ) ? "0" : "-0";
} }
*/ */
long l = (long) v; long l = (long) v;
if ( l == v ) if ( l == v )
return Long.toString(l); return Long.toString(l);
if ( Double.isNaN(v) ) if ( Double.isNaN(v) )
return JSTR_NAN; return JSTR_NAN;
if ( Double.isInfinite(v) ) if ( Double.isInfinite(v) )
return (v<0? JSTR_NEGINF: JSTR_POSINF); return (v<0? JSTR_NEGINF: JSTR_POSINF);
return Float.toString((float)v); return Float.toString((float)v);
} }
@@ -268,11 +288,11 @@ public class LuaDouble extends LuaNumber {
} }
public LuaNumber optnumber(LuaNumber defval) { public LuaNumber optnumber(LuaNumber defval) {
return this; return this;
} }
public boolean isnumber() { public boolean isnumber() {
return true; return true;
} }
public boolean isstring() { public boolean isstring() {
@@ -287,14 +307,14 @@ public class LuaDouble extends LuaNumber {
public LuaNumber checknumber() { return this; } public LuaNumber checknumber() { return this; }
public double checkdouble() { return v; } public double checkdouble() { return v; }
public String checkjstring() { public String checkjstring() {
return tojstring(); return tojstring();
} }
public LuaString checkstring() { public LuaString checkstring() {
return LuaString.valueOf(tojstring()); return LuaString.valueOf(tojstring());
} }
public boolean isvalidkey() { public boolean isvalidkey() {
return !Double.isNaN(v); return !Double.isNaN(v);
} }
} }

Binary file not shown.

View File

@@ -75,6 +75,10 @@ public class LuaError extends RuntimeException {
String m = getMessage(); String m = getMessage();
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>

Binary file not shown.

View File

@@ -22,17 +22,17 @@
package org.luaj.vm2; 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 {
@@ -57,11 +57,11 @@ public class LuaFunction extends LuaValue {
} }
public LuaFunction optfunction(LuaFunction defval) { public LuaFunction optfunction(LuaFunction defval) {
return this; return this;
} }
public LuaValue getmetatable() { public LuaValue getmetatable() {
return s_metatable; return s_metatable;
} }
public String tojstring() { public String tojstring() {
@@ -72,12 +72,15 @@ public class LuaFunction extends LuaValue {
return valueOf(tojstring()); return valueOf(tojstring());
} }
/** 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,17 +21,17 @@
******************************************************************************/ ******************************************************************************/
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)}
* functions. This ensures that policies regarding pooling of instances are * functions. This ensures that policies regarding pooling of instances are
* encapsulated. * encapsulated.
* <p> * <p>
* There are no API's specific to LuaInteger that are useful beyond what is already * There are no API's specific to LuaInteger that are useful beyond what is already
* exposed in {@link LuaValue}. * exposed in {@link LuaValue}.
* *
* @see LuaValue * @see LuaValue
@@ -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,76 +143,123 @@ 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; }
// string comparison // string comparison
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;
} }
public double checkdouble() { public double checkdouble() {
return v; return v;
} }
public String checkjstring() { public String checkjstring() {
return String.valueOf(v); return String.valueOf(v);
} }
public LuaString checkstring() { public LuaString checkstring() {
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,31 +28,31 @@ 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.
* <p> * <p>
* Because lua string values are more nearly sequences of bytes than * Because lua string values are more nearly sequences of bytes than
* sequences of characters or unicode code points, the {@link LuaString} * sequences of characters or unicode code points, the {@link LuaString}
* implementation holds the string value in an internal byte array. * implementation holds the string value in an internal byte array.
* <p> * <p>
* {@link LuaString} values are not considered mutable once constructed, * {@link LuaString} values are not considered mutable once constructed,
* so multiple {@link LuaString} values can chare a single byte array. * so multiple {@link LuaString} values can chare a single byte array.
* <p> * <p>
* Currently {@link LuaString}s are pooled via a centrally managed weak table. * Currently {@link LuaString}s are pooled via a centrally managed weak table.
* To ensure that as many string values as possible take advantage of this, * To ensure that as many string values as possible take advantage of this,
* Constructors are not exposed directly. As with number, booleans, and nil, * Constructors are not exposed directly. As with number, booleans, and nil,
* instance construction should be via {@link LuaValue#valueOf(byte[])} or similar API. * instance construction should be via {@link LuaValue#valueOf(byte[])} or similar API.
* <p> * <p>
* Because of this pooling, users of LuaString <em>must not directly alter the * Because of this pooling, users of LuaString <em>must not directly alter the
* bytes in a LuaString</em>, or undefined behavior will result. * bytes in a LuaString</em>, or undefined behavior will result.
* <p> * <p>
* When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed. * When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed.
* The functions * The functions
* {@link #lengthAsUtf8(char[])}, * {@link #lengthAsUtf8(char[])},
* {@link #encodeToUtf8(char[], int, byte[], int)}, and * {@link #encodeToUtf8(char[], int, byte[], int)}, and
* {@link #decodeAsUtf8(byte[], int, int)} * {@link #decodeAsUtf8(byte[], int, int)}
* are used to convert back and forth between UTF8 byte arrays and character arrays. * are used to convert back and forth between UTF8 byte arrays and character arrays.
* *
* @see LuaValue * @see LuaValue
@@ -63,15 +63,15 @@ public class LuaString extends LuaValue {
/** The singleton instance for string metatables that forwards to the string functions. /** The singleton instance for string metatables that forwards to the string functions.
* Typically, this is set to the string metatable as a side effect of loading the string * Typically, this is set to the string metatable as a side effect of loading the string
* library, and is read-write to provide flexible behavior by default. When used in a * library, and is read-write to provide flexible behavior by default. When used in a
* server environment where there may be roge scripts, this should be replaced with a * server environment where there may be roge scripts, this should be replaced with a
* read-only table since it is shared across all lua code in this Java VM. * read-only table since it is shared across all lua code in this Java VM.
*/ */
public static LuaValue s_metatable; public static LuaValue s_metatable;
/** The bytes for the string. These <em><b>must not be mutated directly</b></em> because /** The bytes for the string. These <em><b>must not be mutated directly</b></em> because
* the backing may be shared by multiple LuaStrings, and the hash code is * the backing may be shared by multiple LuaStrings, and the hash code is
* computed only at construction time. * computed only at construction time.
* It is exposed only for performance and legacy reasons. */ * It is exposed only for performance and legacy reasons. */
public final byte[] m_bytes; public final byte[] m_bytes;
@@ -84,29 +84,29 @@ public class LuaString extends LuaValue {
/** The hashcode for this string. Computed at construct time. */ /** The hashcode for this string. Computed at construct time. */
private final int m_hashcode; private final int m_hashcode;
/** Size of cache of recent short strings. This is the maximum number of LuaStrings that /** Size of cache of recent short strings. This is the maximum number of LuaStrings that
* will be retained in the cache of recent short strings. Exposed to package for testing. */ * will be retained in the cache of recent short strings. Exposed to package for testing. */
static final int RECENT_STRINGS_CACHE_SIZE = 128; static final int RECENT_STRINGS_CACHE_SIZE = 128;
/** Maximum length of a string to be considered for recent short strings caching. /** Maximum length of a string to be considered for recent short strings caching.
* This effectively limits the total memory that can be spent on the recent strings cache, * This effectively limits the total memory that can be spent on the recent strings cache,
* because no LuaString whose backing exceeds this length will be put into the cache. * because no LuaString whose backing exceeds this length will be put into the cache.
* Exposed to package for testing. */ * Exposed to package for testing. */
static final int RECENT_STRINGS_MAX_LENGTH = 32; static final int RECENT_STRINGS_MAX_LENGTH = 32;
/** Simple cache of recently created strings that are short. /** Simple cache of recently created strings that are short.
* This is simply a list of strings, indexed by their hash codes modulo the cache size * This is simply a list of strings, indexed by their hash codes modulo the cache size
* that have been recently constructed. If a string is being constructed frequently * that have been recently constructed. If a string is being constructed frequently
* from different contexts, it will generally show up as a cache hit and resolve * from different contexts, it will generally show up as a cache hit and resolve
* to the same value. */ * to the same value. */
private static final class RecentShortStrings { private static final class RecentShortStrings {
private static final LuaString recent_short_strings[] = private static final LuaString recent_short_strings[] =
new LuaString[RECENT_STRINGS_CACHE_SIZE]; new LuaString[RECENT_STRINGS_CACHE_SIZE];
} }
/** /**
* Get a {@link LuaString} instance whose bytes match * Get a {@link LuaString} instance whose bytes match
* the supplied Java String using the UTF8 encoding. * the supplied Java String using the UTF8 encoding.
* @param string Java String containing characters to encode as UTF8 * @param string Java String containing characters to encode as UTF8
* @return {@link LuaString} with UTF8 bytes corresponding to the supplied String * @return {@link LuaString} with UTF8 bytes corresponding to the supplied String
*/ */
@@ -120,7 +120,7 @@ public class LuaString extends LuaValue {
/** Construct a {@link LuaString} for a portion of a byte array. /** Construct a {@link LuaString} for a portion of a byte array.
* <p> * <p>
* The array is first be used as the backing for this object, so clients must not change contents. * The array is first be used as the backing for this object, so clients must not change contents.
* If the supplied value for 'len' is more than half the length of the container, the * If the supplied value for 'len' is more than half the length of the container, the
* supplied byte array will be used as the backing, otherwise the bytes will be copied to a * supplied byte array will be used as the backing, otherwise the bytes will be copied to a
* new byte array, and cache lookup may be performed. * new byte array, and cache lookup may be performed.
* <p> * <p>
@@ -172,11 +172,11 @@ public class LuaString extends LuaValue {
/** Construct a {@link LuaString} using the supplied characters as byte values. /** Construct a {@link LuaString} using the supplied characters as byte values.
* <p> * <p>
* Only the low-order 8-bits of each character are used, the remainder is ignored. * Only the low-order 8-bits of each character are used, the remainder is ignored.
* <p> * <p>
* This is most useful for constructing byte sequences that do not conform to UTF8. * This is most useful for constructing byte sequences that do not conform to UTF8.
* @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array.
* @return {@link LuaString} wrapping a copy of the byte buffer * @return {@link LuaString} wrapping a copy of the byte buffer
*/ */
public static LuaString valueOf(char[] bytes) { public static LuaString valueOf(char[] bytes) {
return valueOf(bytes, 0, bytes.length); return valueOf(bytes, 0, bytes.length);
@@ -184,11 +184,11 @@ public class LuaString extends LuaValue {
/** Construct a {@link LuaString} using the supplied characters as byte values. /** Construct a {@link LuaString} using the supplied characters as byte values.
* <p> * <p>
* Only the low-order 8-bits of each character are used, the remainder is ignored. * Only the low-order 8-bits of each character are used, the remainder is ignored.
* <p> * <p>
* This is most useful for constructing byte sequences that do not conform to UTF8. * This is most useful for constructing byte sequences that do not conform to UTF8.
* @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array.
* @return {@link LuaString} wrapping a copy of the byte buffer * @return {@link LuaString} wrapping a copy of the byte buffer
*/ */
public static LuaString valueOf(char[] bytes, int off, int len) { public static LuaString valueOf(char[] bytes, int off, int len) {
byte[] b = new byte[len]; byte[] b = new byte[len];
@@ -215,7 +215,7 @@ public class LuaString extends LuaValue {
* The LuaString returned will either be a new LuaString containing the byte array, * The LuaString returned will either be a new LuaString containing the byte array,
* or be an existing LuaString used already having the same value. * or be an existing LuaString used already having the same value.
* <p> * <p>
* The caller must not mutate the contents of the byte array after this call, as * The caller must not mutate the contents of the byte array after this call, as
* it may be used elsewhere due to recent short string caching. * it may be used elsewhere due to recent short string caching.
* @param bytes byte buffer * @param bytes byte buffer
* @return {@link LuaString} wrapping the byte buffer * @return {@link LuaString} wrapping the byte buffer
@@ -241,11 +241,11 @@ public class LuaString extends LuaValue {
} }
public boolean isstring() { public boolean isstring() {
return true; return true;
} }
public LuaValue getmetatable() { public LuaValue getmetatable() {
return s_metatable; return s_metatable;
} }
public int type() { public int type() {
@@ -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; }
@@ -310,14 +320,14 @@ public class LuaString extends LuaValue {
public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); } public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); }
public Buffer concat(Buffer rhs) { return rhs.concatTo(this); } public Buffer concat(Buffer rhs) { return rhs.concatTo(this); }
public LuaValue concatTo(LuaNumber lhs) { return concatTo(lhs.strvalue()); } public LuaValue concatTo(LuaNumber lhs) { return concatTo(lhs.strvalue()); }
public LuaValue concatTo(LuaString lhs) { public LuaValue concatTo(LuaString lhs) {
byte[] b = new byte[lhs.m_length+this.m_length]; byte[] b = new byte[lhs.m_length+this.m_length];
System.arraycopy(lhs.m_bytes, lhs.m_offset, b, 0, lhs.m_length); System.arraycopy(lhs.m_bytes, lhs.m_offset, b, 0, lhs.m_length);
System.arraycopy(this.m_bytes, this.m_offset, b, lhs.m_length, this.m_length); System.arraycopy(this.m_bytes, this.m_offset, b, lhs.m_length, this.m_length);
return valueUsing(b, 0, b.length); return valueUsing(b, 0, b.length);
} }
// string comparison // string comparison
public int strcmp(LuaValue lhs) { return -lhs.strcmp(this); } public int strcmp(LuaValue lhs) { return -lhs.strcmp(this); }
public int strcmp(LuaString rhs) { public int strcmp(LuaString rhs) {
for ( int i=0, j=0; i<m_length && j<rhs.m_length; ++i, ++j ) { for ( int i=0, j=0; i<m_length && j<rhs.m_length; ++i, ++j ) {
@@ -329,9 +339,9 @@ public class LuaString extends LuaValue {
} }
/** Check for number in arithmetic, or throw aritherror */ /** Check for number in arithmetic, or throw aritherror */
private double checkarith() { private double checkarith() {
double d = scannumber(); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
aritherror(); aritherror();
return d; return d;
} }
@@ -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();
@@ -368,15 +384,15 @@ public class LuaString extends LuaValue {
public boolean isint() { public boolean isint() {
double d = scannumber(); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
return false; return false;
int i = (int) d; int i = (int) d;
return i == d; return i == d;
} }
public boolean islong() { public boolean islong() {
double d = scannumber(); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
return false; return false;
long l = (long) d; long l = (long) d;
return l == d; return l == d;
@@ -398,7 +414,7 @@ public class LuaString extends LuaValue {
return checkint(); return checkint();
} }
public LuaInteger optinteger(LuaInteger defval) { public LuaInteger optinteger(LuaInteger defval) {
return checkinteger(); return checkinteger();
} }
@@ -411,15 +427,15 @@ public class LuaString extends LuaValue {
} }
public LuaString optstring(LuaString defval) { public LuaString optstring(LuaString defval) {
return this; return this;
} }
public LuaValue tostring() { public LuaValue tostring() {
return this; return this;
} }
public String optjstring(String defval) { public String optjstring(String defval) {
return tojstring(); return tojstring();
} }
public LuaString strvalue() { public LuaString strvalue() {
@@ -429,7 +445,7 @@ public class LuaString extends LuaValue {
/** Take a substring using Java zero-based indexes for begin and end or range. /** Take a substring using Java zero-based indexes for begin and end or range.
* @param beginIndex The zero-based index of the first character to include. * @param beginIndex The zero-based index of the first character to include.
* @param endIndex The zero-based index of position after the last character. * @param endIndex The zero-based index of position after the last character.
* @return LuaString which is a substring whose first character is at offset * @return LuaString which is a substring whose first character is at offset
* beginIndex and extending for (endIndex - beginIndex ) characters. * beginIndex and extending for (endIndex - beginIndex ) characters.
*/ */
public LuaString substring( int beginIndex, int endIndex ) { public LuaString substring( int beginIndex, int endIndex ) {
@@ -476,7 +492,7 @@ public class LuaString extends LuaValue {
return val.raweq(this); return val.raweq(this);
} }
public boolean raweq( LuaString s ) { public boolean raweq( LuaString s ) {
if ( this == s ) if ( this == s )
return true; return true;
if ( s.m_length != m_length ) if ( s.m_length != m_length )
@@ -503,7 +519,7 @@ public class LuaString extends LuaValue {
public static boolean equals( byte[] a, int i, byte[] b, int j, int n ) { public static boolean equals( byte[] a, int i, byte[] b, int j, int n ) {
if ( a.length < i + n || b.length < j + n ) if ( a.length < i + n || b.length < j + n )
return false; return false;
while ( --n>=0 ) while ( --n>=0 )
if ( a[i++]!=b[j++] ) if ( a[i++]!=b[j++] )
return false; return false;
return true; return true;
@@ -535,8 +551,8 @@ public class LuaString extends LuaValue {
return luaByte( index ); return luaByte( index );
} }
public String checkjstring() { public String checkjstring() {
return tojstring(); return tojstring();
} }
public LuaString checkstring() { public LuaString checkstring() {
@@ -552,7 +568,7 @@ public class LuaString extends LuaValue {
} }
/** /**
* Copy the bytes of the string into the given byte array. * Copy the bytes of the string into the given byte array.
* @param strOffset offset from which to copy * @param strOffset offset from which to copy
* @param bytes destination byte array * @param bytes destination byte array
* @param arrayOffset offset in destination * @param arrayOffset offset in destination
@@ -626,12 +642,12 @@ public class LuaString extends LuaValue {
/** /**
* Convert to Java String interpreting as utf8 characters. * Convert to Java String interpreting as utf8 characters.
* *
* @param bytes byte array in UTF8 encoding to convert * @param bytes byte array in UTF8 encoding to convert
* @param offset starting index in byte array * @param offset starting index in byte array
* @param length number of bytes to convert * @param length number of bytes to convert
* @return Java String corresponding to the value of bytes interpreted using UTF8 * @return Java String corresponding to the value of bytes interpreted using UTF8
* @see #lengthAsUtf8(char[]) * @see #lengthAsUtf8(char[])
* @see #encodeToUtf8(char[], int, byte[], int) * @see #encodeToUtf8(char[], int, byte[], int)
* @see #isValidUtf8() * @see #isValidUtf8()
@@ -662,7 +678,7 @@ public class LuaString extends LuaValue {
* @see #decodeAsUtf8(byte[], int, int) * @see #decodeAsUtf8(byte[], int, int)
* @see #isValidUtf8() * @see #isValidUtf8()
*/ */
public static int lengthAsUtf8(char[] chars) { public static int lengthAsUtf8(char[] chars) {
int i,b; int i,b;
char c; char c;
for ( i=b=chars.length; --i>=0; ) for ( i=b=chars.length; --i>=0; )
@@ -673,7 +689,7 @@ public class LuaString extends LuaValue {
/** /**
* Encode the given Java string as UTF-8 bytes, writing the result to bytes * Encode the given Java string as UTF-8 bytes, writing the result to bytes
* starting at offset. * starting at offset.
* <p> * <p>
* The string should be measured first with lengthAsUtf8 * The string should be measured first with lengthAsUtf8
* to make sure the given byte array is large enough. * to make sure the given byte array is large enough.
@@ -694,11 +710,11 @@ public class LuaString extends LuaValue {
bytes[j++] = (byte) c; bytes[j++] = (byte) c;
} else if ( c < 0x800 ) { } else if ( c < 0x800 ) {
bytes[j++] = (byte) (0xC0 | ((c>>6) & 0x1f)); bytes[j++] = (byte) (0xC0 | ((c>>6) & 0x1f));
bytes[j++] = (byte) (0x80 | ( c & 0x3f)); bytes[j++] = (byte) (0x80 | ( c & 0x3f));
} else { } else {
bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f)); bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f));
bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f)); bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f));
bytes[j++] = (byte) (0x80 | ( c & 0x3f)); bytes[j++] = (byte) (0x80 | ( c & 0x3f));
} }
} }
return j - off; return j - off;
@@ -714,12 +730,12 @@ public class LuaString extends LuaValue {
for (int i=m_offset,j=m_offset+m_length; i<j;) { for (int i=m_offset,j=m_offset+m_length; i<j;) {
int c = m_bytes[i++]; int c = m_bytes[i++];
if ( c >= 0 ) continue; if ( c >= 0 ) continue;
if ( ((c & 0xE0) == 0xC0) if ( ((c & 0xE0) == 0xC0)
&& i<j && i<j
&& (m_bytes[i++] & 0xC0) == 0x80) continue; && (m_bytes[i++] & 0xC0) == 0x80) continue;
if ( ((c & 0xF0) == 0xE0) if ( ((c & 0xF0) == 0xE0)
&& i+1<j && i+1<j
&& (m_bytes[i++] & 0xC0) == 0x80 && (m_bytes[i++] & 0xC0) == 0x80
&& (m_bytes[i++] & 0xC0) == 0x80) continue; && (m_bytes[i++] & 0xC0) == 0x80) continue;
return false; return false;
} }
@@ -728,32 +744,32 @@ public class LuaString extends LuaValue {
// --------------------- number conversion ----------------------- // --------------------- number conversion -----------------------
/** /**
* convert to a number using baee 10 or base 16 if it starts with '0x', * convert to a number using baee 10 or base 16 if it starts with '0x',
* or NIL if it can't be converted * or NIL if it can't be converted
* @return IntValue, DoubleValue, or NIL depending on the content of the string. * @return IntValue, DoubleValue, or NIL depending on the content of the string.
* @see LuaValue#tonumber() * @see LuaValue#tonumber()
*/ */
public LuaValue tonumber() { public LuaValue tonumber() {
double d = scannumber(); double d = scannumber();
return Double.isNaN(d)? NIL: valueOf(d); return Double.isNaN(d)? NIL: valueOf(d);
} }
/** /**
* convert to a number using a supplied base, or NIL if it can't be converted * convert to a number using a supplied base, or NIL if it can't be converted
* @param base the base to use, such as 10 * @param base the base to use, such as 10
* @return IntValue, DoubleValue, or NIL depending on the content of the string. * @return IntValue, DoubleValue, or NIL depending on the content of the string.
* @see LuaValue#tonumber() * @see LuaValue#tonumber()
*/ */
public LuaValue tonumber( int base ) { public LuaValue tonumber( int base ) {
double d = scannumber( base ); double d = scannumber( base );
return Double.isNaN(d)? NIL: valueOf(d); return Double.isNaN(d)? NIL: valueOf(d);
} }
/** /**
* Convert to a number in base 10, or base 16 if the string starts with '0x', * Convert to a number in base 10, or base 16 if the string starts with '0x',
* or return Double.NaN if it cannot be converted to a number. * or return Double.NaN if it cannot be converted to a number.
* @return double value if conversion is valid, or Double.NaN if not * @return double value if conversion is valid, or Double.NaN if not
*/ */
public double scannumber() { public double scannumber() {
int i=m_offset,j=m_offset+m_length; int i=m_offset,j=m_offset+m_length;
@@ -761,16 +777,19 @@ 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;
} }
/** /**
* Convert to a number in a base, or return Double.NaN if not a number. * Convert to a number in a base, or return Double.NaN if not a number.
* @param base the base to use between 2 and 36 * @param base the base to use between 2 and 36
* @return double value if conversion is valid, or Double.NaN if not * @return double value if conversion is valid, or Double.NaN if not
*/ */
public double scannumber(int base) { public double scannumber(int base) {
if ( base < 2 || base > 36 ) if ( base < 2 || base > 36 )
@@ -788,17 +807,23 @@ public class LuaString extends LuaValue {
* @param base the base to use, such as 10 * @param base the base to use, such as 10
* @param start the index to start searching from * @param start the index to start searching from
* @param end the first index beyond the search range * @param end the first index beyond the search range
* @return double value if conversion is valid, * @return double value if conversion is valid,
* 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 )
return Double.NaN; return Double.NaN;
x = x * base + digit; x = x * base + digit;
if ( x < 0 ) if ( x < 0 )
return Double.NaN; // overflow return Double.NaN; // overflow
@@ -810,7 +835,7 @@ public class LuaString extends LuaValue {
* Scan and convert a double value, or return Double.NaN if not a double. * Scan and convert a double value, or return Double.NaN if not a double.
* @param start the index to start searching from * @param start the index to start searching from
* @param end the first index beyond the search range * @param end the first index beyond the search range
* @return double value if conversion is valid, * @return double value if conversion is valid,
* or Double.NaN if not * or Double.NaN if not
*/ */
private double scandouble(int start, int end) { private double scandouble(int start, int end) {
@@ -833,7 +858,7 @@ public class LuaString extends LuaValue {
c[i-start] = (char) m_bytes[i]; c[i-start] = (char) m_bytes[i];
try { try {
return Double.parseDouble(new String(c)); return Double.parseDouble(new String(c));
} catch ( Exception e ) { } catch ( Exception e ) {
return Double.NaN; return Double.NaN;
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -25,23 +25,23 @@ import java.lang.ref.WeakReference;
import java.util.Vector; import java.util.Vector;
/** /**
* Subclass of {@link LuaValue} for representing lua tables. * Subclass of {@link LuaValue} for representing lua tables.
* <p> * <p>
* Almost all API's implemented in {@link LuaTable} are defined and documented in {@link LuaValue}. * Almost all API's implemented in {@link LuaTable} are defined and documented in {@link LuaValue}.
* <p> * <p>
* If a table is needed, the one of the type-checking functions can be used such as * If a table is needed, the one of the type-checking functions can be used such as
* {@link #istable()}, * {@link #istable()},
* {@link #checktable()}, or * {@link #checktable()}, or
* {@link #opttable(LuaTable)} * {@link #opttable(LuaTable)}
* <p> * <p>
* The main table operations are defined on {@link LuaValue} * The main table operations are defined on {@link LuaValue}
* for getting and setting values with and without metatag processing: * for getting and setting values with and without metatag processing:
* <ul> * <ul>
* <li>{@link #get(LuaValue)}</li> * <li>{@link #get(LuaValue)}</li>
* <li>{@link #set(LuaValue,LuaValue)}</li> * <li>{@link #set(LuaValue,LuaValue)}</li>
* <li>{@link #rawget(LuaValue)}</li> * <li>{@link #rawget(LuaValue)}</li>
* <li>{@link #rawset(LuaValue,LuaValue)}</li> * <li>{@link #rawset(LuaValue,LuaValue)}</li>
* <li>plus overloads such as {@link #get(String)}, {@link #get(int)}, and so on</li> * <li>plus overloads such as {@link #get(String)}, {@link #get(int)}, and so on</li>
* </ul> * </ul>
* <p> * <p>
* To iterate over key-value pairs from Java, use * To iterate over key-value pairs from Java, use
@@ -56,7 +56,7 @@ import java.util.Vector;
* }}</pre> * }}</pre>
* *
* <p> * <p>
* As with other types, {@link LuaTable} instances should be constructed via one of the table constructor * As with other types, {@link LuaTable} instances should be constructed via one of the table constructor
* methods on {@link LuaValue}: * methods on {@link LuaValue}:
* <ul> * <ul>
* <li>{@link LuaValue#tableOf()} empty table</li> * <li>{@link LuaValue#tableOf()} empty table</li>
@@ -92,7 +92,7 @@ public class LuaTable extends LuaValue implements Metatable {
hash = NOBUCKETS; hash = NOBUCKETS;
} }
/** /**
* Construct table with preset capacity. * Construct table with preset capacity.
* @param narray capacity of array part * @param narray capacity of array part
* @param nhash capacity of hash part * @param nhash capacity of hash part
@@ -102,9 +102,9 @@ public class LuaTable extends LuaValue implements Metatable {
} }
/** /**
* Construct table with named and unnamed parts. * Construct table with named and unnamed parts.
* @param named Named elements in order {@code key-a, value-a, key-b, value-b, ... } * @param named Named elements in order {@code key-a, value-a, key-b, value-b, ... }
* @param unnamed Unnamed elements in order {@code value-1, value-2, ... } * @param unnamed Unnamed elements in order {@code value-1, value-2, ... }
* @param lastarg Additional unnamed values beyond {@code unnamed.length} * @param lastarg Additional unnamed values beyond {@code unnamed.length}
*/ */
public LuaTable(LuaValue[] named, LuaValue[] unnamed, Varargs lastarg) { public LuaTable(LuaValue[] named, LuaValue[] unnamed, Varargs lastarg) {
@@ -123,17 +123,17 @@ public class LuaTable extends LuaValue implements Metatable {
} }
/** /**
* Construct table of unnamed elements. * Construct table of unnamed elements.
* @param varargs Unnamed elements in order {@code value-1, value-2, ... } * @param varargs Unnamed elements in order {@code value-1, value-2, ... }
*/ */
public LuaTable(Varargs varargs) { public LuaTable(Varargs varargs) {
this(varargs,1); this(varargs,1);
} }
/** /**
* Construct table of unnamed elements. * Construct table of unnamed elements.
* @param varargs Unnamed elements in order {@code value-1, value-2, ... } * @param varargs Unnamed elements in order {@code value-1, value-2, ... }
* @param firstarg the index in varargs of the first argument to include in the table * @param firstarg the index in varargs of the first argument to include in the table
*/ */
public LuaTable(Varargs varargs, int firstarg) { public LuaTable(Varargs varargs, int firstarg) {
int nskip = firstarg-1; int nskip = firstarg-1;
@@ -152,8 +152,8 @@ public class LuaTable extends LuaValue implements Metatable {
return "table"; return "table";
} }
public boolean istable() { public boolean istable() {
return true; return true;
} }
public LuaTable checktable() { public LuaTable checktable() {
@@ -185,17 +185,17 @@ public class LuaTable extends LuaValue implements Metatable {
return v; return v;
} }
/** /**
* Get the length of the array part of the table. * Get the length of the array part of the table.
* @return length of the array part, does not relate to count of objects in the table. * @return length of the array part, does not relate to count of objects in the table.
*/ */
protected int getArrayLength() { protected int getArrayLength() {
return array.length; return array.length;
} }
/** /**
* Get the length of the hash part of the table. * Get the length of the hash part of the table.
* @return length of the hash part, does not relate to count of objects in the table. * @return length of the hash part, does not relate to count of objects in the table.
*/ */
protected int getHashLength() { protected int getHashLength() {
return hash.length; return hash.length;
@@ -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
@@ -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 );
} }
@@ -294,35 +294,35 @@ public class LuaTable extends LuaValue implements Metatable {
} }
/** Remove the element at a position in a list-table /** Remove the element at a position in a list-table
* *
* @param pos the position to remove * @param pos the position to remove
* @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;
} }
/** Insert an element at a position in a list-table /** Insert an element at a position in a list-table
* *
* @param pos the position to remove * @param pos the position to remove
* @param value The value to insert * @param value The value to insert
*/ */
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;
} }
} }
@@ -355,14 +355,14 @@ public class LuaTable extends LuaValue implements Metatable {
return rawlen(); return rawlen();
} }
public LuaValue len() { public LuaValue len() {
final LuaValue h = metatag(LEN); final LuaValue h = metatag(LEN);
if (h.toboolean()) if (h.toboolean())
return h.call(this); return h.call(this);
return LuaInteger.valueOf(rawlen()); return LuaInteger.valueOf(rawlen());
} }
public int rawlen() { public int rawlen() {
int a = getArrayLength(); int a = getArrayLength();
int n = a+1,m=0; int n = a+1,m=0;
while ( !rawget(n).isnil() ) { while ( !rawget(n).isnil() ) {
@@ -380,7 +380,7 @@ public class LuaTable extends LuaValue implements Metatable {
} }
/** /**
* Get the next element after a particular key in the table * Get the next element after a particular key in the table
* @return key,value or nil * @return key,value or nil
*/ */
public Varargs next( LuaValue key ) { public Varargs next( LuaValue key ) {
@@ -388,7 +388,7 @@ 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;
@@ -441,8 +441,8 @@ public class LuaTable extends LuaValue implements Metatable {
} }
/** /**
* Get the next element after a particular key in the * Get the next element after a particular key in the
* contiguous array part of a table * contiguous array part of a table
* @return key,value or none * @return key,value or none
*/ */
public Varargs inext(LuaValue key) { public Varargs inext(LuaValue key) {
@@ -472,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) )
@@ -517,7 +518,7 @@ public class LuaTable extends LuaValue implements Metatable {
} }
} }
/** /**
* Find the hashtable slot to use * Find the hashtable slot to use
* @param key key to look for * @param key key to look for
* @return slot to use * @return slot to use
@@ -719,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] );
} }
@@ -766,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 );
@@ -779,7 +780,7 @@ public class LuaTable extends LuaValue implements Metatable {
// //
// implemented heap sort from wikipedia // implemented heap sort from wikipedia
// //
// Only sorts the contiguous array part. // Only sorts the contiguous array part.
// //
/** Sort the table using a comparator. /** Sort the table using a comparator.
* @param comparator {@link LuaValue} to be called to compare elements. * @param comparator {@link LuaValue} to be called to compare elements.
@@ -789,33 +790,35 @@ public class LuaTable extends LuaValue implements Metatable {
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 ) if ( n > 1 )
--n; heapSort(n, comparator.isnil() ? null : comparator);
if ( n > 1 )
heapSort(n, 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;
@@ -823,32 +826,19 @@ 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) { /** This may be deprecated in a future release.
LuaValue a = array[i];
array[i] = array[j];
array[j] = a;
}
/** 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
* */ * */
public int keyCount() { public int keyCount() {
LuaValue k = LuaValue.NIL; LuaValue k = LuaValue.NIL;
@@ -859,9 +849,9 @@ public class LuaTable extends LuaValue implements Metatable {
} }
} }
/** This may be deprecated in a future release. /** This may be deprecated in a future release.
* It is recommended to use next() instead * It is recommended to use next() instead
* @return array of keys in the table * @return array of keys in the table
* */ * */
public LuaValue[] keys() { public LuaValue[] keys() {
Vector l = new Vector(); Vector l = new Vector();

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.

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

@@ -276,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:

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -24,16 +24,16 @@ package org.luaj.vm2;
/** /**
* Class to encapsulate varargs values, either as part of a variable argument list, or multiple return values. * Class to encapsulate varargs values, either as part of a variable argument list, or multiple return values.
* <p> * <p>
* To construct varargs, use one of the static methods such as * To construct varargs, use one of the static methods such as
* {@code LuaValue.varargsOf(LuaValue,LuaValue)} * {@code LuaValue.varargsOf(LuaValue,LuaValue)}
* <p> * <p>
* <p> * <p>
* Any LuaValue can be used as a stand-in for Varargs, for both calls and return values. * Any LuaValue can be used as a stand-in for Varargs, for both calls and return values.
* When doing so, nargs() will return 1 and arg1() or arg(1) will return this. * When doing so, nargs() will return 1 and arg1() or arg(1) will return this.
* This simplifies the case when calling or implementing varargs functions with only * This simplifies the case when calling or implementing varargs functions with only
* 1 argument or 1 return value. * 1 argument or 1 return value.
* <p> * <p>
* Varargs can also be derived from other varargs by appending to the front with a call * Varargs can also be derived from other varargs by appending to the front with a call
* such as {@code LuaValue.varargsOf(LuaValue,Varargs)} * such as {@code LuaValue.varargsOf(LuaValue,Varargs)}
* or by taking a portion of the args using {@code Varargs.subargs(int start)} * or by taking a portion of the args using {@code Varargs.subargs(int start)}
* <p> * <p>
@@ -57,22 +57,22 @@ public abstract class Varargs {
abstract public LuaValue arg( int i ); abstract public LuaValue arg( int i );
/** /**
* Get the number of arguments, or 0 if there are none. * Get the number of arguments, or 0 if there are none.
* @return number of arguments. * @return number of arguments.
*/ */
abstract public int narg(); abstract public int narg();
/** /**
* Get the first argument in the list. * Get the first argument in the list.
* @return LuaValue which is first in the list, or LuaValue.NIL if there are no values. * @return LuaValue which is first in the list, or LuaValue.NIL if there are no values.
* @see Varargs#arg(int) * @see Varargs#arg(int)
* @see LuaValue#NIL * @see LuaValue#NIL
*/ */
abstract public LuaValue arg1(); abstract public LuaValue arg1();
/** /**
* Evaluate any pending tail call and return result. * Evaluate any pending tail call and return result.
* @return the evaluated tail call result * @return the evaluated tail call result
*/ */
public Varargs eval() { return this; } public Varargs eval() { return this; }
@@ -88,7 +88,7 @@ public abstract class Varargs {
// utilities to get specific arguments and type-check them. // utilities to get specific arguments and type-check them.
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** Gets the type of argument {@code i} /** Gets the type of argument {@code i}
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return int value corresponding to one of the LuaValue integer type values * @return int value corresponding to one of the LuaValue integer type values
* @see LuaValue#TNIL * @see LuaValue#TNIL
@@ -117,20 +117,20 @@ public abstract class Varargs {
public boolean isfunction(int i) { return arg(i).isfunction(); } public boolean isfunction(int i) { return arg(i).isfunction(); }
/** Tests if argument i is a number. /** Tests if argument i is a number.
* Since anywhere a number is required, a string can be used that * Since anywhere a number is required, a string can be used that
* is a number, this will return true for both numbers and * is a number, this will return true for both numbers and
* strings that can be interpreted as numbers. * strings that can be interpreted as numbers.
* @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 true if the argument exists and is a number or * @return true if the argument exists and is a number or
* string that can be interpreted as a number, false otherwise * string that can be interpreted as a number, false otherwise
* @see LuaValue#TNUMBER * @see LuaValue#TNUMBER
* @see LuaValue#TSTRING * @see LuaValue#TSTRING
* */ * */
public boolean isnumber(int i) { return arg(i).isnumber(); } public boolean isnumber(int i) { return arg(i).isnumber(); }
/** Tests if argument i is a string. /** Tests if argument i is a string.
* Since all lua numbers can be used where strings are used, * Since all lua numbers can be used where strings are used,
* this will return true for both strings and numbers. * this will return true for both strings and numbers.
* @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 true if the argument exists and is a string or number, false otherwise * @return true if the argument exists and is a string or number, false otherwise
* @see LuaValue#TNUMBER * @see LuaValue#TNUMBER
@@ -167,7 +167,7 @@ public abstract class Varargs {
/** Return argument i as a boolean value, {@code defval} if nil, or throw a LuaError if any other type. /** Return argument i as a boolean value, {@code defval} if nil, or throw a LuaError if any other 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
* @return true if argument i is boolean true, false if it is false, or defval if not supplied or nil * @return true if argument i is boolean true, false if it is false, or defval if not supplied or nil
* @exception LuaError if the argument is not a lua boolean * @exception LuaError if the argument is not a lua boolean
* */ * */
public boolean optboolean(int i, boolean defval) { return arg(i).optboolean(defval); } public boolean optboolean(int i, boolean defval) { return arg(i).optboolean(defval); }
@@ -256,7 +256,7 @@ public abstract class Varargs {
* */ * */
public Object optuserdata(int i, Object defval) { return arg(i).optuserdata(defval); } public Object optuserdata(int i, Object defval) { return arg(i).optuserdata(defval); }
/** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, /** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass,
* {@code defval} if nil, or throw a LuaError if any other type. * {@code defval} if nil, or throw a LuaError if any other 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
* @param c the class to which the userdata instance must be assignable * @param c the class to which the userdata instance must be assignable
@@ -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
@@ -363,7 +363,7 @@ public abstract class Varargs {
* */ * */
public Object checkuserdata(int i) { return arg(i).checkuserdata(); } public Object checkuserdata(int i) { return arg(i).checkuserdata(); }
/** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, /** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass,
* or throw an error if any other type. * or throw an error if any other 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
* @param c the class to which the userdata instance must be assignable * @param c the class to which the userdata instance must be assignable
@@ -387,7 +387,7 @@ public abstract class Varargs {
public LuaValue checknotnil(int i) { return arg(i).checknotnil(); } public LuaValue checknotnil(int i) { return arg(i).checknotnil(); }
/** Performs test on argument i as a LuaValue when a user-supplied assertion passes, or throw an error. /** Performs test on argument i as a LuaValue when a user-supplied assertion passes, or throw an error.
* Returns normally if the value of {@code test} is {@code true}, otherwise throws and argument error with * Returns normally if the value of {@code test} is {@code true}, otherwise throws and argument error with
* the supplied message, {@code msg}. * the supplied message, {@code msg}.
* @param test user supplied assertion to test against * @param test user supplied assertion to test against
* @param i the index to report in any error message * @param i the index to report in any error message
@@ -404,20 +404,20 @@ public abstract class Varargs {
return i>narg() || arg(i).isnil(); return i>narg() || arg(i).isnil();
} }
/** Convert argument {@code i} to java boolean based on lua rules for boolean evaluation. /** Convert argument {@code i} to java boolean based on lua rules for boolean evaluation.
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return {@code false} if argument i is nil or false, otherwise {@code true} * @return {@code false} if argument i is nil or false, otherwise {@code true}
* */ * */
public boolean toboolean(int i) { return arg(i).toboolean(); } public boolean toboolean(int i) { return arg(i).toboolean(); }
/** Return argument i as a java byte value, discarding any fractional part and truncating, /** Return argument i as a java byte value, discarding any fractional part and truncating,
* or 0 if not a number. * or 0 if not a number.
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return byte value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 * @return byte value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
* */ * */
public byte tobyte(int i) { return arg(i).tobyte(); } public byte tobyte(int i) { return arg(i).tobyte(); }
/** Return argument i as a java char value, discarding any fractional part and truncating, /** Return argument i as a java char value, discarding any fractional part and truncating,
* or 0 if not a number. * or 0 if not a number.
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return char value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 * @return char value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
@@ -430,21 +430,21 @@ public abstract class Varargs {
* */ * */
public double todouble(int i) { return arg(i).todouble(); } public double todouble(int i) { return arg(i).todouble(); }
/** Return argument i as a java float value, discarding excess fractional part and truncating, /** Return argument i as a java float value, discarding excess fractional part and truncating,
* or 0 if not a number. * or 0 if not a number.
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return float value with excess fraction discarded and truncated if necessary if argument i is number, otherwise 0 * @return float value with excess fraction discarded and truncated if necessary if argument i is number, otherwise 0
* */ * */
public float tofloat(int i) { return arg(i).tofloat(); } public float tofloat(int i) { return arg(i).tofloat(); }
/** Return argument i as a java int value, discarding any fractional part and truncating, /** Return argument i as a java int value, discarding any fractional part and truncating,
* or 0 if not a number. * or 0 if not a number.
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return int value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 * @return int value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
* */ * */
public int toint(int i) { return arg(i).toint(); } public int toint(int i) { return arg(i).toint(); }
/** Return argument i as a java long value, discarding any fractional part and truncating, /** Return argument i as a java long value, discarding any fractional part and truncating,
* or 0 if not a number. * or 0 if not a number.
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return long value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 * @return long value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
@@ -457,7 +457,7 @@ public abstract class Varargs {
* */ * */
public String tojstring(int i) { return arg(i).tojstring(); } public String tojstring(int i) { return arg(i).tojstring(); }
/** Return argument i as a java short value, discarding any fractional part and truncating, /** Return argument i as a java short value, discarding any fractional part and truncating,
* or 0 if not a number. * or 0 if not a number.
* @param i the index of the argument to convert, 1 is the first argument * @param i the index of the argument to convert, 1 is the first argument
* @return short value with fraction discarded and truncated if necessary if argument i is number, otherwise 0 * @return short value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
@@ -477,8 +477,8 @@ public abstract class Varargs {
* */ * */
public Object touserdata(int i,Class c) { return arg(i).touserdata(c); } public Object touserdata(int i,Class c) { return arg(i).touserdata(c); }
/** Convert the list of varargs values to a human readable java String. /** Convert the list of varargs values to a human readable java String.
* @return String value in human readable form such as {1,2}. * @return String value in human readable form such as {1,2}.
*/ */
public String tojstring() { public String tojstring() {
Buffer sb = new Buffer(); Buffer sb = new Buffer();
@@ -491,8 +491,8 @@ public abstract class Varargs {
return sb.tojstring(); return sb.tojstring();
} }
/** Convert the value or values to a java String using Varargs.tojstring() /** Convert the value or values to a java String using Varargs.tojstring()
* @return String value in human readable form. * @return String value in human readable form.
* @see Varargs#tojstring() * @see Varargs#tojstring()
*/ */
public String toString() { return tojstring(); } public String toString() { return tojstring(); }
@@ -537,28 +537,28 @@ 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);
} }
} }
/** Varargs implemenation backed by two values. /** Varargs implemenation backed by two values.
* <p> * <p>
* This is an internal class not intended to be used directly. * This is an internal class not intended to be used directly.
* Instead use the corresponding static method on LuaValue. * Instead use the corresponding static method on LuaValue.
* *
* @see LuaValue#varargsOf(LuaValue, Varargs) * @see LuaValue#varargsOf(LuaValue, Varargs)
*/ */
static final class PairVarargs extends Varargs { static final class PairVarargs extends Varargs {
private final LuaValue v1; private final LuaValue v1;
private final Varargs v2; private final Varargs v2;
/** Construct a Varargs from an two LuaValue. /** Construct a Varargs from an two LuaValue.
* <p> * <p>
* This is an internal class not intended to be used directly. * This is an internal class not intended to be used directly.
* Instead use the corresponding static method on LuaValue. * Instead use the corresponding static method on LuaValue.
* *
* @see LuaValue#varargsOf(LuaValue, Varargs) * @see LuaValue#varargsOf(LuaValue, Varargs)
*/ */
PairVarargs(LuaValue v1, Varargs v2) { PairVarargs(LuaValue v1, Varargs v2) {
@@ -571,8 +571,8 @@ public abstract class Varargs {
public int narg() { public int narg() {
return 1+v2.narg(); return 1+v2.narg();
} }
public LuaValue arg1() { public LuaValue arg1() {
return v1; return v1;
} }
public Varargs subargs(final int start) { public Varargs subargs(final int start) {
if (start == 1) if (start == 1)
@@ -585,22 +585,22 @@ public abstract class Varargs {
} }
} }
/** Varargs implemenation backed by an array of LuaValues /** Varargs implemenation backed by an array of LuaValues
* <p> * <p>
* This is an internal class not intended to be used directly. * This is an internal class not intended to be used directly.
* Instead use the corresponding static methods on LuaValue. * Instead use the corresponding static methods on LuaValue.
* *
* @see LuaValue#varargsOf(LuaValue[]) * @see LuaValue#varargsOf(LuaValue[])
* @see LuaValue#varargsOf(LuaValue[], Varargs) * @see LuaValue#varargsOf(LuaValue[], Varargs)
*/ */
static final class ArrayVarargs extends Varargs { static final class ArrayVarargs extends Varargs {
private final LuaValue[] v; private final LuaValue[] v;
private final Varargs r; private final Varargs r;
/** Construct a Varargs from an array of LuaValue. /** Construct a Varargs from an array of LuaValue.
* <p> * <p>
* This is an internal class not intended to be used directly. * This is an internal class not intended to be used directly.
* Instead use the corresponding static methods on LuaValue. * Instead use the corresponding static methods on LuaValue.
* *
* @see LuaValue#varargsOf(LuaValue[]) * @see LuaValue#varargsOf(LuaValue[])
* @see LuaValue#varargsOf(LuaValue[], Varargs) * @see LuaValue#varargsOf(LuaValue[], Varargs)
*/ */
@@ -631,11 +631,11 @@ public abstract class Varargs {
} }
} }
/** Varargs implemenation backed by an array of LuaValues /** Varargs implemenation backed by an array of LuaValues
* <p> * <p>
* This is an internal class not intended to be used directly. * This is an internal class not intended to be used directly.
* Instead use the corresponding static methods on LuaValue. * Instead use the corresponding static methods on LuaValue.
* *
* @see LuaValue#varargsOf(LuaValue[], int, int) * @see LuaValue#varargsOf(LuaValue[], int, int)
* @see LuaValue#varargsOf(LuaValue[], int, int, Varargs) * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs)
*/ */
@@ -644,11 +644,11 @@ public abstract class Varargs {
private final LuaValue[] v; private final LuaValue[] v;
private final int length; private final int length;
private final Varargs more; private final Varargs more;
/** Construct a Varargs from an array of LuaValue. /** Construct a Varargs from an array of LuaValue.
* <p> * <p>
* This is an internal class not intended to be used directly. * This is an internal class not intended to be used directly.
* Instead use the corresponding static methods on LuaValue. * Instead use the corresponding static methods on LuaValue.
* *
* @see LuaValue#varargsOf(LuaValue[], int, int) * @see LuaValue#varargsOf(LuaValue[], int, int)
*/ */
ArrayPartVarargs(LuaValue[] v, int offset, int length) { ArrayPartVarargs(LuaValue[] v, int offset, int length) {
@@ -657,11 +657,11 @@ public abstract class Varargs {
this.length = length; this.length = length;
this.more = LuaValue.NONE; this.more = LuaValue.NONE;
} }
/** Construct a Varargs from an array of LuaValue and additional arguments. /** Construct a Varargs from an array of LuaValue and additional arguments.
* <p> * <p>
* This is an internal class not intended to be used directly. * This is an internal class not intended to be used directly.
* Instead use the corresponding static method on LuaValue. * Instead use the corresponding static method on LuaValue.
* *
* @see LuaValue#varargsOf(LuaValue[], int, int, Varargs) * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs)
*/ */
public ArrayPartVarargs(LuaValue[] v, int offset, int length, Varargs more) { public ArrayPartVarargs(LuaValue[] v, int offset, int length, Varargs more) {
@@ -676,8 +676,8 @@ public abstract class Varargs {
public int narg() { public int narg() {
return length + more.narg(); return length + more.narg();
} }
public LuaValue arg1() { public LuaValue arg1() {
return length>0? v[offset]: more.arg1(); return length>0? v[offset]: more.arg1();
} }
public Varargs subargs(int start) { public Varargs subargs(int start) {
if (start <= 0) if (start <= 0)
@@ -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