diff --git a/README.html b/README.html index 67c794c6..a67a8596 100644 --- a/README.html +++ b/README.html @@ -469,6 +469,18 @@ Time is a represented as number of milliseconds since the epoch, and most time and date formatting, locales, and other features are not implemented. +

Coroutine Library

+The coroutine library is implemented using one JavaThread per coroutine. +This allows coroutine.yield() can be called from anywhere, +as with the yield-from-anywhere patch in C-based lua. + +

+Luaj uses WeakReferences and the OrphanedThread error to ensure that coroutines that are no longer referenced +are properly garbage collected. For thread safety, OrphanedThread should not be caught by Java code. +See LuaThread +and OrphanedThread +javadoc for details. +

Debug Library

The debug library is not included by default by JmePlatform.standardGlobals() or JsePlatform.standardGlobsls() . @@ -505,7 +517,7 @@ See a longer sample in examples/lua/swingapp.lua for details, or try ru

-The Java ME platform does not include this library, and it cannot be made to work because of the lack of a reflection API in Java SE. +The Java ME platform does not include this library, and it cannot be made to work because of the lack of a reflection API in Java ME.

The lua connand line tool includes luajava. @@ -734,6 +746,7 @@ and LuaForge:

  • Fix lua command vararg values passed into main script to match what is in global arg table
  • Add arithmetic metatag processing when left hand side is a number and right hand side has metatable
  • Fix load(func) when mutiple string fragments are supplied by calls to func
  • +
  • Allow access to public members of private inner classes where possible
  • @@ -744,5 +757,6 @@ and LuaForge:
  • using both version 1 and 2 libraries together in the same java vm has not been tested
  • module() and setfenv() only partially supported for lau2java or luajc compiled lua
  • values associated with weak keys may linger longer than expected +
  • behavior of luaj when a SecurityManager is used has not been fully characterized diff --git a/src/core/org/luaj/vm2/LuaThread.java b/src/core/org/luaj/vm2/LuaThread.java index 47448088..e62c16b3 100644 --- a/src/core/org/luaj/vm2/LuaThread.java +++ b/src/core/org/luaj/vm2/LuaThread.java @@ -47,12 +47,12 @@ import org.luaj.vm2.lib.DebugLib; * 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. - * On the other hand, if a {@link LuaThread} is created, then yields - * without ever entering a completed state, then the garbage collector - * may not be able to determine that the thread needs to be collected, - * and this could cause a memory and resource leak. It is recommended - * that all coroutines that are created are resumed until they are in - * a completed state. + *

    + * 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. * * @see LuaValue * @see JsePlatform @@ -64,7 +64,10 @@ public class LuaThread extends LuaValue { public static LuaValue s_metatable; public static int coroutine_count = 0; - + + /** Interval at which to check for lua threads that are no longer referenced. + * This can be changed by Java startup code if desired. + */ static long thread_orphan_check_interval = 30000; private static final int STATUS_INITIAL = 0; diff --git a/src/core/org/luaj/vm2/OrphanedThread.java b/src/core/org/luaj/vm2/OrphanedThread.java index 08840d04..668217be 100644 --- a/src/core/org/luaj/vm2/OrphanedThread.java +++ b/src/core/org/luaj/vm2/OrphanedThread.java @@ -21,19 +21,20 @@ ******************************************************************************/ package org.luaj.vm2; - -/** - * Error sublcass that indicates a lua thread that is no longer referenced has been detected. - * - * The java thread in which this is thrown should correspond to a LuaThread being used as a - * coroutine that could not possibly be resumed again because there are no more references - * to the LuaThread with which it is associated. Rather than locking up resources forever, - * this error is thrown, and should fall through all the way to the thread's run() method. - * - * Java code mixed with the luaj vm should not catch this error because it may occur when - * the coroutine is not running, so any processing done during error handling could break - * the thread-safety of the application because other lua processing could be going on in - * a different thread. +/** + * {@link java.lang.Error} sublcass that indicates a lua thread that is no + * longer referenced has been detected. + *

    + * The java thread in which this is thrown should correspond to a + * {@link LuaThread} being used as a coroutine that could not possibly be + * resumed again because there are no more references to the LuaThread with + * which it is associated. Rather than locking up resources forever, this error + * is thrown, and should fall through all the way to the thread's {@link Thread.run}() method. + *

    + * Java code mixed with the luaj vm should not catch this error because it may + * occur when the coroutine is not running, so any processing done during error + * handling could break the thread-safety of the application because other lua + * processing could be going on in a different thread. */ public class OrphanedThread extends Error { diff --git a/src/jse/org/luaj/vm2/lib/jse/JavaClass.java b/src/jse/org/luaj/vm2/lib/jse/JavaClass.java index 32e12fbb..aabbb2ee 100644 --- a/src/jse/org/luaj/vm2/lib/jse/JavaClass.java +++ b/src/jse/org/luaj/vm2/lib/jse/JavaClass.java @@ -76,9 +76,17 @@ class JavaClass extends JavaInstance implements CoerceJavaToLua.Coercion { if ( fields == null ) { Map m = new HashMap(); Field[] f = ((Class)m_instance).getFields(); - for ( int i=0; i