New Lua functions
[jpcrr.git] / mnj / lua / Lua.java
blob52086969c31982ec88c87065ea7cfe7aa6af490f
1 /* $Header: //info.ravenbrook.com/project/jili/version/1.1/code/mnj/lua/Lua.java#3 $
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
3 * All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject
11 * to the following conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 package mnj.lua;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.io.DataOutputStream;
30 import java.io.IOException;
31 import java.io.Reader;
32 import java.util.Enumeration;
33 import java.util.Stack;
34 import java.util.Vector;
36 /**
37 * <p>
38 * Encapsulates a Lua execution environment. A lot of Jill's public API
39 * manifests as public methods in this class. A key part of the API is
40 * the ability to call Lua functions from Java (ultimately, all Lua code
41 * is executed in this manner).
42 * </p>
44 * <p>
45 * The Stack
46 * </p>
48 * <p>
49 * All arguments to Lua functions and all results returned by Lua
50 * functions are placed onto a stack. The stack can be indexed by an
51 * integer in the same way as the PUC-Rio implementation. A positive
52 * index is an absolute index and ranges from 1 (the bottom-most
53 * element) through to <var>n</var> (the top-most element),
54 * where <var>n</var> is the number of elements on the stack. Negative
55 * indexes are relative indexes, -1 is the top-most element, -2 is the
56 * element underneath that, and so on. 0 is not used.
57 * </p>
59 * <p>
60 * Note that in Jill the stack is used only for passing arguments and
61 * returning results, unlike PUC-Rio.
62 * </p>
64 * <p>
65 * The protocol for calling a function is described in the {@link #call}
66 * method. In brief: push the function onto the stack, then push the
67 * arguments to the call.
68 * </p>
70 * <p>
71 * The methods {@link #push}, {@link #pop}, {@link #value},
72 * {@link #getTop}, {@link #setTop} are used to manipulate the stack.
73 * </p>
75 public final class Lua
77 /** Version string. */
78 public static final String VERSION = "Lua 5.1 (Jill 1.0.1)";
80 /** Table of globals (global variables). This actually shared across
81 * all threads (with the same main thread), but kept in each Lua
82 * thread as an optimisation.
84 private LuaTable global;
85 private LuaTable registry;
87 /** Reference the main Lua thread. Itself if this is the main Lua
88 * thread.
90 private Lua main;
92 /** VM data stack.
94 private Slot[] stack = new Slot[0];
95 /**
96 * One more than the highest stack slot that has been written to
97 * (ever).
98 * Used by {@link #stacksetsize} to determine which stack slots
99 * need nilling when growing the stack.
101 int stackhighwater; // = 0;
103 * Number of active elemements in the VM stack. Should always be
104 * <code><= stack.length</code>.
106 private int stackSize; // = 0;
108 * The base stack element for this stack frame. If in a Lua function
109 * then this is the element indexed by operand field 0; if in a Java
110 * functipn then this is the element indexed by Lua.value(1).
112 private int base; // = 0;
114 int nCcalls; // = 0;
115 /** Instruction to resume execution at. Index into code array. */
116 private int savedpc; // = 0;
118 * Vector of CallInfo records. Actually it's a Stack which is a
119 * subclass of Vector, but it mostly the Vector methods that are used.
121 private Stack<Object> civ = new Stack<Object>();
123 civ.addElement(new CallInfo());
125 /** CallInfo record for currently active function. */
126 private CallInfo ci()
128 return (CallInfo)civ.lastElement();
131 /** Open Upvalues. All UpVal objects that reference the VM stack.
132 * openupval is a java.util.Vector of UpVal stored in order of stack
133 * slot index: higher stack indexes are stored at higher Vector
134 * positions.
136 private Vector<Object> openupval = new Vector<Object>();
138 int hookcount;
139 int basehookcount;
140 boolean allowhook = true;
141 Hook hook;
142 int hookmask;
144 /** Number of list items to accumulate before a SETLIST instruction. */
145 static final int LFIELDS_PER_FLUSH = 50;
147 /** Limit for table tag-method chains (to avoid loops) */
148 private static final int MAXTAGLOOP = 100;
151 * The current error handler (set by {@link #pcall}). A Lua
152 * function to call.
154 private Object errfunc;
157 * thread activation status.
159 private int status;
161 /** Metatable for primitive types. Shared between all threads. */
162 private LuaTable[] metatable;
165 * Maximum number of local variables per function. As per
166 * LUAI_MAXVARS from "luaconf.h". Default access so that {@link
167 * FuncState} can see it.
169 static final int MAXVARS = 200;
170 static final int MAXSTACK = 250;
171 static final int MAXUPVALUES = 60;
174 * Stored in Slot.r to denote a numeric value (which is stored at
175 * Slot.d).
177 static final Object NUMBER = new Object();
180 * Spare Slot used for a temporary.
182 private static final Slot SPARE_SLOT = new Slot();
185 * Registry key for loaded modules.
187 static final String LOADED = "_LOADED";
190 * Used to construct a Lua thread that shares its global state with
191 * another Lua state.
193 private Lua(Lua L)
195 // Copy the global state, that's shared across all threads that
196 // share the same main thread, into the new Lua thread.
197 // Any more than this and the global state should be shunted to a
198 // separate object (as it is in PUC-Rio).
199 this.global = L.global;
200 this.registry = L.registry;
201 this.metatable = L.metatable;
202 this.main = L;
205 //////////////////////////////////////////////////////////////////////
206 // Public API
209 * Creates a fresh Lua state.
211 public Lua()
213 this.global = new LuaTable();
214 this.registry = new LuaTable();
215 this.metatable = new LuaTable[NUM_TAGS];
216 this.main = this;
220 * Equivalent of LUA_MULTRET.
222 // Required, by vmPoscall, to be negative.
223 public static final int MULTRET = -1;
225 * The Lua <code>nil</code> value.
227 public static final Object NIL = new Object();
229 // Lua type tags, from lua.h
230 /** Lua type tag, representing no stack value. */
231 public static final int TNONE = -1;
232 /** Lua type tag, representing <code>nil</code>. */
233 public static final int TNIL = 0;
234 /** Lua type tag, representing boolean. */
235 public static final int TBOOLEAN = 1;
236 // TLIGHTUSERDATA not available. :todo: make available?
237 /** Lua type tag, representing numbers. */
238 public static final int TNUMBER = 3;
239 /** Lua type tag, representing strings. */
240 public static final int TSTRING = 4;
241 /** Lua type tag, representing tables. */
242 public static final int TTABLE = 5;
243 /** Lua type tag, representing functions. */
244 public static final int TFUNCTION = 6;
245 /** Lua type tag, representing userdata. */
246 public static final int TUSERDATA = 7;
247 /** Lua type tag, representing threads. */
248 public static final int TTHREAD = 8;
249 /** Number of type tags. Should be one more than the
250 * last entry in the list of tags.
252 private static final int NUM_TAGS = 9;
253 /** Names for above type tags, starting from {@link #TNIL}.
254 * Equivalent to luaT_typenames.
256 private static final String[] TYPENAME =
258 "nil", "boolean", "userdata", "number",
259 "string", "table", "function", "userdata", "thread"
263 * Minimum stack size that Lua Java functions gets. May turn out to
264 * be silly / redundant.
266 public static final int MINSTACK = 20;
268 /** Status code, returned from pcall and friends, that indicates the
269 * thread has yielded.
271 public static final int YIELD = 1;
272 /** Status code, returned from pcall and friends, that indicates
273 * a runtime error.
275 public static final int ERRRUN = 2;
276 /** Status code, returned from pcall and friends, that indicates
277 * a syntax error.
279 public static final int ERRSYNTAX = 3;
280 /** Status code, returned from pcall and friends, that indicates
281 * a memory allocation error.
283 private static final int ERRMEM = 4;
284 /** Status code, returned from pcall and friends, that indicates
285 * an error whilst running the error handler function.
287 public static final int ERRERR = 5;
288 /** Status code, returned from loadFile and friends, that indicates
289 * an IO error.
291 public static final int ERRFILE = 6;
293 // Enums for gc().
294 /** Action, passed to {@link #gc}, that requests the GC to stop. */
295 public static final int GCSTOP = 0;
296 /** Action, passed to {@link #gc}, that requests the GC to restart. */
297 public static final int GCRESTART = 1;
298 /** Action, passed to {@link #gc}, that requests a full collection. */
299 public static final int GCCOLLECT = 2;
300 /** Action, passed to {@link #gc}, that returns amount of memory
301 * (in Kibibytes) in use (by the entire Java runtime).
303 public static final int GCCOUNT = 3;
304 /** Action, passed to {@link #gc}, that returns the remainder of
305 * dividing the amount of memory in use by 1024.
307 public static final int GCCOUNTB = 4;
308 /** Action, passed to {@link #gc}, that requests an incremental
309 * garbage collection be performed.
311 public static final int GCSTEP = 5;
312 /** Action, passed to {@link #gc}, that sets a new value for the
313 * <var>pause</var> of the collector.
315 public static final int GCSETPAUSE = 6;
316 /** Action, passed to {@link #gc}, that sets a new values for the
317 * <var>step multiplier</var> of the collector.
319 public static final int GCSETSTEPMUL = 7;
321 // Some of the hooks, etc, aren't implemented, so remain private.
322 private static final int HOOKLINE = 2;
324 * When {@link Hook} callback is called as a line hook, its
325 * <var>ar.event</var> field is <code>HOOKCOUNT</code>.
327 public static final int HOOKCOUNT = 3;
328 private static final int HOOKTAILRET = 4;
330 private static final int MASKLINE = 1 << HOOKLINE;
332 * Bitmask that specifies count hook in call to {@link #setHook}.
334 public static final int MASKCOUNT = 1 << HOOKCOUNT;
338 * Calls a Lua value. Normally this is called on functions, but the
339 * semantics of Lua permit calls on any value as long as its metatable
340 * permits it.
342 * In order to call a function, the function must be
343 * pushed onto the stack, then its arguments must be
344 * {@link #push pushed} onto the stack; the first argument is pushed
345 * directly after the function,
346 * then the following arguments are pushed in order (direct
347 * order). The parameter <var>nargs</var> specifies the number of
348 * arguments (which may be 0).
350 * When the function returns the function value on the stack and all
351 * the arguments are removed from the stack and replaced with the
352 * results of the function, adjusted to the number specified by
353 * <var>nresults</var>. So the first result from the function call will
354 * be at the same index where the function was immediately prior to
355 * calling this method.
357 * @param nargs The number of arguments in this function call.
358 * @param nresults The number of results required.
360 public void call(int nargs, int nresults)
362 apiChecknelems(nargs+1);
363 int func = stackSize - (nargs + 1);
364 this.vmCall(func, nresults);
368 * Closes a Lua state. In this implementation, this method does
369 * nothing.
371 public void close()
376 * Concatenate values (usually strings) on the stack.
377 * <var>n</var> values from the top of the stack are concatenated, as
378 * strings, and replaced with the resulting string.
379 * @param n the number of values to concatenate.
381 public void concat(int n)
383 apiChecknelems(n);
384 if (n >= 2)
386 vmConcat(n, (stackSize - base) - 1);
387 pop(n-1);
389 else if (n == 0) // push empty string
391 push("");
392 } // else n == 1; nothing to do
396 * Creates a new empty table and returns it.
397 * @param narr number of array elements to pre-allocate.
398 * @param nrec number of non-array elements to pre-allocate.
399 * @return a fresh table.
400 * @see #newTable
402 public LuaTable createTable(int narr, int nrec)
404 return new LuaTable(narr, nrec);
408 * Dumps a function as a binary chunk.
409 * @param function the Lua function to dump.
410 * @param writer the stream that receives the dumped binary.
411 * @throws IOException when writer does.
413 public static void dump(Object function, OutputStream writer)
414 throws IOException
416 if (!(function instanceof LuaFunction))
418 throw new IOException("Cannot dump " + typeName(type(function)));
420 LuaFunction f = (LuaFunction)function;
421 uDump(f.proto(), writer, false);
425 * Tests for equality according to the semantics of Lua's
426 * <code>==</code> operator (so may call metamethods).
427 * @param o1 a Lua value.
428 * @param o2 another Lua value.
429 * @return true when equal.
431 public boolean equal(Object o1, Object o2)
433 if (o1 instanceof Double)
435 return o1.equals(o2);
437 return vmEqualRef(o1, o2);
441 * Generates a Lua error using the error message.
442 * @param message the error message.
443 * @return never.
445 public int error(Object message)
447 return gErrormsg(message);
451 * Control garbage collector. Note that in Jill most of the options
452 * to this function make no sense and they will not do anything.
453 * @param what specifies what GC action to take.
454 * @param data data that may be used by the action.
455 * @return varies.
457 public int gc(int what, int data)
459 Runtime rt;
461 switch (what)
463 case GCSTOP:
464 return 0;
465 case GCRESTART:
466 case GCCOLLECT:
467 case GCSTEP:
468 System.gc();
469 return 0;
470 case GCCOUNT:
471 rt = Runtime.getRuntime();
472 return (int)((rt.totalMemory() - rt.freeMemory()) / 1024);
473 case GCCOUNTB:
474 rt = Runtime.getRuntime();
475 return (int)((rt.totalMemory() - rt.freeMemory()) % 1024);
476 case GCSETPAUSE:
477 case GCSETSTEPMUL:
478 return 0;
480 return 0;
484 * Returns the environment table of the Lua value.
485 * @param o the Lua value.
486 * @return its environment table.
488 public LuaTable getFenv(Object o)
490 if (o instanceof LuaFunction)
492 LuaFunction f = (LuaFunction)o;
493 return f.getEnv();
495 if (o instanceof LuaJavaCallback)
497 // :todo: implement this case.
498 return null;
501 if (o instanceof LuaUserdata)
503 LuaUserdata u = (LuaUserdata)o;
504 return u.getEnv();
506 if (o instanceof Lua)
508 Lua l = (Lua)o;
509 return l.global;
511 return null;
515 * Get a field from a table (or other object).
516 * @param t The object whose field to retrieve.
517 * @param field The name of the field.
518 * @return the Lua value
520 public Object getField(Object t, String field)
522 return getTable(t, field);
526 * Get a global variable.
527 * @param name The name of the global variable.
528 * @return The value of the global variable.
530 public Object getGlobal(String name)
532 return getField(global, name);
536 * Gets the global environment. The global environment, where global
537 * variables live, is returned as a <code>LuaTable</code>. Note that
538 * modifying this table has exactly the same effect as creating or
539 * changing global variables from within Lua.
540 * @return The global environment as a table.
542 public LuaTable getGlobals()
544 return global;
547 /** Get metatable.
548 * @param o the Lua value whose metatable to retrieve.
549 * @return The metatable, or null if there is no metatable.
551 public LuaTable getMetatable(Object o)
553 LuaTable mt;
555 if (o instanceof LuaTable)
557 LuaTable t = (LuaTable)o;
558 mt = t.getMetatable();
560 else if (o instanceof LuaUserdata)
562 LuaUserdata u = (LuaUserdata)o;
563 mt = u.getMetatable();
565 else
567 mt = metatable[type(o)];
569 return mt;
573 * Gets the registry table.
575 public LuaTable getRegistry()
577 return registry;
581 * Indexes into a table and returns the value.
582 * @param t the Lua value to index.
583 * @param k the key whose value to return.
584 * @return the value t[k].
586 public Object getTable(Object t, Object k)
588 Slot s = new Slot(k);
589 Slot v = new Slot();
590 vmGettable(t, s, v);
591 return v.asObject();
595 * Gets the number of elements in the stack. If the stack is not
596 * empty then this is the index of the top-most element.
597 * @return number of stack elements.
599 public int getTop()
601 return stackSize - base;
605 * Insert Lua value into stack immediately at specified index. Values
606 * in stack at that index and higher get pushed up.
607 * @param o the Lua value to insert into the stack.
608 * @param idx the stack index at which to insert.
610 public void insert(Object o, int idx)
612 idx = absIndexUnclamped(idx);
613 stackInsertAt(o, idx);
617 * Tests that an object is a Lua boolean.
618 * @param o the Object to test.
619 * @return true if and only if the object is a Lua boolean.
621 public static boolean isBoolean(Object o)
623 return o instanceof Boolean;
627 * Tests that an object is a Lua function implementated in Java (a Lua
628 * Java Function).
629 * @param o the Object to test.
630 * @return true if and only if the object is a Lua Java Function.
632 public static boolean isJavaFunction(Object o)
634 return o instanceof LuaJavaCallback;
638 * Tests that an object is a Lua function (implemented in Lua or
639 * Java).
640 * @param o the Object to test.
641 * @return true if and only if the object is a function.
643 public static boolean isFunction(Object o)
645 return o instanceof LuaFunction ||
646 o instanceof LuaJavaCallback;
650 * Tests that a Lua thread is the main thread.
651 * @return true if and only if is the main thread.
653 public boolean isMain()
655 return this == main;
659 * Tests that an object is Lua <code>nil</code>.
660 * @param o the Object to test.
661 * @return true if and only if the object is Lua <code>nil</code>.
663 public static boolean isNil(Object o)
665 return NIL == o;
669 * Tests that an object is a Lua number or a string convertible to a
670 * number.
671 * @param o the Object to test.
672 * @return true if and only if the object is a number or a convertible string.
674 public static boolean isNumber(Object o)
676 SPARE_SLOT.setObject(o);
677 return tonumber(SPARE_SLOT, NUMOP);
681 * Tests that an object is a Lua string or a number (which is always
682 * convertible to a string).
683 * @param o the Object to test.
684 * @return true if and only if object is a string or number.
686 public static boolean isString(Object o)
688 return o instanceof String || o instanceof Double;
692 * Tests that an object is a Lua table.
693 * @param o the Object to test.
694 * @return <code>true</code> if and only if the object is a Lua table.
696 public static boolean isTable(Object o)
698 return o instanceof LuaTable;
702 * Tests that an object is a Lua thread.
703 * @param o the Object to test.
704 * @return <code>true</code> if and only if the object is a Lua thread.
706 public static boolean isThread(Object o)
708 return o instanceof Lua;
712 * Tests that an object is a Lua userdata.
713 * @param o the Object to test.
714 * @return true if and only if the object is a Lua userdata.
716 public static boolean isUserdata(Object o)
718 return o instanceof LuaUserdata;
722 * <p>
723 * Tests that an object is a Lua value. Returns <code>true</code> for
724 * an argument that is a Jill representation of a Lua value,
725 * <code>false</code> for Java references that are not Lua values.
726 * For example <code>isValue(new LuaTable())</code> is
727 * <code>true</code>, but <code>isValue(new Object[] { })</code> is
728 * <code>false</code> because Java arrays are not a representation of
729 * any Lua value.
730 * </p>
731 * <p>
732 * PUC-Rio Lua provides no
733 * counterpart for this method because in their implementation it is
734 * impossible to get non Lua values on the stack, whereas in Jill it
735 * is common to mix Lua values with ordinary, non Lua, Java objects.
736 * </p>
737 * @param o the Object to test.
738 * @return true if and if it represents a Lua value.
740 public static boolean isValue(Object o)
742 return o == NIL ||
743 o instanceof Boolean ||
744 o instanceof String ||
745 o instanceof Double ||
746 o instanceof LuaFunction ||
747 o instanceof LuaJavaCallback ||
748 o instanceof LuaTable ||
749 o instanceof LuaUserdata;
753 * Compares two Lua values according to the semantics of Lua's
754 * <code>&lt;</code> operator, so may call metamethods.
755 * @param o1 the left-hand operand.
756 * @param o2 the right-hand operand.
757 * @return true when <code>o1 < o2</code>.
759 public boolean lessThan(Object o1, Object o2)
761 Slot a = new Slot(o1);
762 Slot b = new Slot(o2);
763 return vmLessthan(a, b);
767 * <p>
768 * Loads a Lua chunk in binary or source form.
769 * Comparable to C's lua_load. If the chunk is determined to be
770 * binary then it is loaded directly. Otherwise the chunk is assumed
771 * to be a Lua source chunk and compilation is required first; the
772 * <code>InputStream</code> is used to create a <code>Reader</code>
773 * using the UTF-8 encoding
774 * (using a second argument of <code>"UTF-8"</code> to the
775 * {@link java.io.InputStreamReader#InputStreamReader(java.io.InputStream,
776 * java.lang.String)}
777 * constructor) and the Lua source is compiled.
778 * </p>
779 * <p>
780 * If successful, The compiled chunk, a Lua function, is pushed onto
781 * the stack and a zero status code is returned. Otherwise a non-zero
782 * status code is returned to indicate an error and the error message
783 * is pushed onto the stack.
784 * </p>
785 * @param in The binary chunk as an InputStream, for example from
786 * {@link Class#getResourceAsStream}.
787 * @param chunkname The name of the chunk.
788 * @return A status code.
790 public int load(InputStream in, String chunkname)
792 push(new LuaInternal(in, chunkname));
793 return pcall(0, 1, null);
797 * Loads a Lua chunk in source form.
798 * Comparable to C's lua_load. This method takes a {@link
799 * java.io.Reader} parameter,
800 * and is normally used to load Lua chunks in source form.
801 * However, it if the input looks like it is the output from Lua's
802 * <code>string.dump</code> function then it will be processed as a
803 * binary chunk.
804 * In every other respect this method is just like {@link
805 * #load(InputStream, String)}.
806 * @param in The source chunk as a Reader, for example from
807 * <code>java.io.InputStreamReader(Class.getResourceAsStream())</code>.
808 * @param chunkname The name of the chunk.
809 * @return A status code.
810 * @see java.io.InputStreamReader
812 public int load(Reader in, String chunkname)
814 push(new LuaInternal(in, chunkname));
815 return pcall(0, 1, null);
819 * Slowly get the next key from a table. Unlike most other functions
820 * in the API this one uses the stack. The top-of-stack is popped and
821 * used to find the next key in the table at the position specified by
822 * index. If there is a next key then the key and its value are
823 * pushed onto the stack and <code>true</code> is returned.
824 * Otherwise (the end of the table has been reached)
825 * <code>false</code> is returned.
826 * @param idx stack index of table.
827 * @return true if and only if there are more keys in the table.
828 * @deprecated Use {@link #tableKeys} enumeration protocol instead.
830 public boolean next(int idx)
832 Object o = value(idx);
833 // :todo: api check
834 LuaTable t = (LuaTable)o;
835 Object key = value(-1);
836 pop(1);
837 Enumeration<Object> e = t.keys();
838 if (key == NIL)
840 if (e.hasMoreElements())
842 key = e.nextElement();
843 push(key);
844 push(t.getlua(key));
845 return true;
847 return false;
849 while (e.hasMoreElements())
851 Object k = e.nextElement();
852 if (k.equals(key))
854 if (e.hasMoreElements())
856 key = e.nextElement();
857 push(key);
858 push(t.getlua(key));
859 return true;
861 return false;
864 // protocol error which we could potentially diagnose.
865 return false;
869 * Creates a new empty table and returns it.
870 * @return a fresh table.
871 * @see #createTable
873 public LuaTable newTable()
875 return new LuaTable();
879 * Creates a new Lua thread and returns it.
880 * @return a new Lua thread.
882 public Lua newThread()
884 return new Lua(this);
888 * Wraps an arbitrary Java reference in a Lua userdata and returns it.
889 * @param ref the Java reference to wrap.
890 * @return the new LuaUserdata.
892 public LuaUserdata newUserdata(Object ref)
894 return new LuaUserdata(ref);
898 * Return the <em>length</em> of a Lua value. For strings this is
899 * the string length; for tables, this is result of the <code>#</code>
900 * operator; for other values it is 0.
901 * @param o a Lua value.
902 * @return its length.
904 public static int objLen(Object o)
906 if (o instanceof String)
908 String s = (String)o;
909 return s.length();
911 if (o instanceof LuaTable)
913 LuaTable t = (LuaTable)o;
914 return t.getn();
916 if (o instanceof Double)
918 return vmTostring(o).length();
920 return 0;
925 * <p>
926 * Protected {@link #call}. <var>nargs</var> and
927 * <var>nresults</var> have the same meaning as in {@link #call}.
928 * If there are no errors during the call, this method behaves as
929 * {@link #call}. Any errors are caught, the error object (usually
930 * a message) is pushed onto the stack, and a non-zero error code is
931 * returned.
932 * </p>
933 * <p>
934 * If <var>er</var> is <code>null</code> then the error object that is
935 * on the stack is the original error object. Otherwise
936 * <var>ef</var> specifies an <em>error handling function</em> which
937 * is called when the original error is generated; its return value
938 * becomes the error object left on the stack by <code>pcall</code>.
939 * </p>
940 * @param nargs number of arguments.
941 * @param nresults number of result required.
942 * @param ef error function to call in case of error.
943 * @return 0 if successful, else a non-zero error code.
945 public int pcall(int nargs, int nresults, Object ef)
947 apiChecknelems(nargs+1);
948 int restoreStack = stackSize - (nargs + 1);
949 // Most of this code comes from luaD_pcall
950 int restoreCi = civ.size();
951 int oldnCcalls = nCcalls;
952 Object old_errfunc = errfunc;
953 errfunc = ef;
954 boolean old_allowhook = allowhook;
955 int errorStatus = 0;
958 call(nargs, nresults);
960 catch (LuaError e)
962 fClose(restoreStack); // close eventual pending closures
963 dSeterrorobj(e.errorStatus, restoreStack);
964 nCcalls = oldnCcalls;
965 civ.setSize(restoreCi);
966 CallInfo ci = ci();
967 base = ci.base();
968 savedpc = ci.savedpc();
969 allowhook = old_allowhook;
970 errorStatus = e.errorStatus;
972 catch (OutOfMemoryError e)
974 fClose(restoreStack); // close eventual pending closures
975 dSeterrorobj(ERRMEM, restoreStack);
976 nCcalls = oldnCcalls;
977 civ.setSize(restoreCi);
978 CallInfo ci = ci();
979 base = ci.base();
980 savedpc = ci.savedpc();
981 allowhook = old_allowhook;
982 errorStatus = ERRMEM;
984 errfunc = old_errfunc;
985 return errorStatus;
989 * Removes (and discards) the top-most <var>n</var> elements from the stack.
990 * @param n the number of elements to remove.
992 public void pop(int n)
994 if (n < 0)
996 throw new IllegalArgumentException();
998 stacksetsize(stackSize - n);
1002 * Pushes a value onto the stack in preparation for calling a
1003 * function (or returning from one). See {@link #call} for
1004 * the protocol to be used for calling functions. See {@link
1005 * #pushNumber} for pushing numbers, and {@link #pushValue} for
1006 * pushing a value that is already on the stack.
1007 * @param o the Lua value to push.
1009 public void push(Object o)
1011 // see also a private overloaded version of this for Slot.
1012 stackAdd(o);
1016 * Push boolean onto the stack.
1017 * @param b the boolean to push.
1019 public void pushBoolean(boolean b)
1021 push(valueOfBoolean(b));
1025 * Push literal string onto the stack.
1026 * @param s the string to push.
1028 public void pushLiteral(String s)
1030 push(s);
1033 /** Push nil onto the stack. */
1034 public void pushNil()
1036 push(NIL);
1040 * Pushes a number onto the stack. See also {@link #push}.
1041 * @param d the number to push.
1043 public void pushNumber(double d)
1045 // :todo: optimise to avoid creating Double instance
1046 push(new Double(d));
1050 * Push string onto the stack.
1051 * @param s the string to push.
1053 public void pushString(String s)
1055 push(s);
1059 * Copies a stack element onto the top of the stack.
1060 * Equivalent to <code>L.push(L.value(idx))</code>.
1061 * @param idx stack index of value to push.
1063 public void pushValue(int idx)
1065 // :todo: optimised to avoid creating Double instance
1066 push(value(idx));
1070 * Implements equality without metamethods.
1071 * @param o1 the first Lua value to compare.
1072 * @param o2 the other Lua value.
1073 * @return true if and only if they compare equal.
1075 public static boolean rawEqual(Object o1, Object o2)
1077 return oRawequal(o1, o2);
1081 * Gets an element from a table, without using metamethods.
1082 * @param t The table to access.
1083 * @param k The index (key) into the table.
1084 * @return The value at the specified index.
1086 public static Object rawGet(Object t, Object k)
1088 LuaTable table = (LuaTable)t;
1089 return table.getlua(k);
1093 * Gets an element from an array, without using metamethods.
1094 * @param t the array (table).
1095 * @param i the index of the element to retrieve.
1096 * @return the value at the specified index.
1098 public static Object rawGetI(Object t, int i)
1100 LuaTable table = (LuaTable)t;
1101 return table.getnum(i);
1105 * Sets an element in a table, without using metamethods.
1106 * @param t The table to modify.
1107 * @param k The index into the table.
1108 * @param v The new value to be stored at index <var>k</var>.
1110 public void rawSet(Object t, Object k, Object v)
1112 LuaTable table = (LuaTable)t;
1113 table.putlua(this, k, v);
1117 * Sets an element in an array, without using metamethods.
1118 * @param t the array (table).
1119 * @param i the index of the element to set.
1120 * @param v the new value to be stored at index <var>i</var>.
1122 public void rawSetI(Object t, int i, Object v)
1124 apiCheck(t instanceof LuaTable);
1125 LuaTable h = (LuaTable)t;
1126 h.putnum(i, v);
1130 * Register a {@link LuaJavaCallback} as the new value of the global
1131 * <var>name</var>.
1132 * @param name the name of the global.
1133 * @param f the LuaJavaCallback to register.
1135 public void register(String name, LuaJavaCallback f)
1137 setGlobal(name, f);
1141 * Starts and resumes a Lua thread. Threads can be created using
1142 * {@link #newThread}. Once a thread has begun executing it will
1143 * run until it either completes (with error or normally) or has been
1144 * suspended by invoking {@link #yield}.
1145 * @param narg Number of values to pass to thread.
1146 * @return Lua.YIELD, 0, or an error code.
1148 public int resume(int narg)
1150 if (status != YIELD)
1152 if (status != 0)
1153 return resume_error("cannot resume dead coroutine");
1154 else if (civ.size() != 1)
1155 return resume_error("cannot resume non-suspended coroutine");
1157 // assert errfunc == 0 && nCcalls == 0;
1158 protect:
1161 // This block is equivalent to resume from ldo.c
1162 int firstArg = stackSize - narg;
1163 if (status == 0) // start coroutine?
1165 // assert civ.size() == 1 && firstArg > base);
1166 if (vmPrecall(firstArg - 1, MULTRET) != PCRLUA)
1167 break protect;
1169 else // resuming from previous yield
1171 // assert status == YIELD;
1172 status = 0;
1173 if (!isLua(ci())) // 'common' yield
1175 // finish interrupted execution of 'OP_CALL'
1176 // assert ...
1177 if (vmPoscall(firstArg)) // complete it...
1178 stacksetsize(ci().top()); // and correct top
1180 else // yielded inside a hook: just continue its execution
1181 base = ci().base();
1183 vmExecute(civ.size() - 1);
1185 catch (LuaError e)
1187 status = e.errorStatus; // mark thread as 'dead'
1188 dSeterrorobj(e.errorStatus, stackSize);
1189 ci().setTop(stackSize);
1191 return status;
1195 * Set the environment for a function, thread, or userdata.
1196 * @param o Object whose environment will be set.
1197 * @param table Environment table to use.
1198 * @return true if the object had its environment set, false otherwise.
1200 public boolean setFenv(Object o, Object table)
1202 // :todo: consider implementing common env interface for
1203 // LuaFunction, LuaJavaCallback, LuaUserdata, Lua. One cast to an
1204 // interface and an interface method call may be shorter
1205 // than this mess.
1206 LuaTable t = (LuaTable)table;
1208 if (o instanceof LuaFunction)
1210 LuaFunction f = (LuaFunction)o;
1211 f.setEnv(t);
1212 return true;
1214 if (o instanceof LuaJavaCallback)
1216 // :todo: implement this case.
1217 return false;
1219 if (o instanceof LuaUserdata)
1221 LuaUserdata u = (LuaUserdata)o;
1222 u.setEnv(t);
1223 return true;
1225 if (o instanceof Lua)
1227 Lua l = (Lua)o;
1228 l.global = t;
1229 return true;
1231 return false;
1235 * Set a field in a Lua value.
1236 * @param t Lua value of which to set a field.
1237 * @param name Name of field to set.
1238 * @param v new Lua value for field.
1240 public void setField(Object t, String name, Object v)
1242 Slot s = new Slot(name);
1243 vmSettable(t, s, v);
1247 * Sets the metatable for a Lua value.
1248 * @param o Lua value of which to set metatable.
1249 * @param mt The new metatable.
1251 public void setMetatable(Object o, Object mt)
1253 if (isNil(mt))
1255 mt = null;
1257 else
1259 apiCheck(mt instanceof LuaTable);
1261 LuaTable mtt = (LuaTable)mt;
1262 if (o instanceof LuaTable)
1264 LuaTable t = (LuaTable)o;
1265 t.setMetatable(mtt);
1267 else if (o instanceof LuaUserdata)
1269 LuaUserdata u = (LuaUserdata)o;
1270 u.setMetatable(mtt);
1272 else
1274 metatable[type(o)] = mtt;
1279 * Set a global variable.
1280 * @param name name of the global variable to set.
1281 * @param value desired new value for the variable.
1283 public void setGlobal(String name, Object value)
1285 Slot s = new Slot(name);
1286 vmSettable(global, s, value);
1290 * Does the equivalent of <code>t[k] = v</code>.
1291 * @param t the table to modify.
1292 * @param k the index to modify.
1293 * @param v the new value at index <var>k</var>.
1295 public void setTable(Object t, Object k, Object v)
1297 Slot s = new Slot(k);
1298 vmSettable(t, s, v);
1302 * Set the stack top.
1303 * @param n the desired size of the stack (in elements).
1305 public void setTop(int n)
1307 if (n < 0)
1309 throw new IllegalArgumentException();
1311 stacksetsize(base+n);
1315 * Status of a Lua thread.
1316 * @return 0, an error code, or Lua.YIELD.
1318 public int status()
1320 return status;
1324 * Returns an {@link java.util.Enumeration} for the keys of a table.
1325 * @param t a Lua table.
1326 * @return an Enumeration object.
1328 public Enumeration<Object> tableKeys(Object t)
1330 if (!(t instanceof LuaTable))
1332 error("table required");
1333 // NOTREACHED
1335 return ((LuaTable)t).keys();
1339 * Convert to boolean.
1340 * @param o Lua value to convert.
1341 * @return the resulting primitive boolean.
1343 public boolean toBoolean(Object o)
1345 return !(o == NIL || Boolean.FALSE.equals(o));
1349 * Convert to integer and return it. Returns 0 if cannot be
1350 * converted.
1351 * @param o Lua value to convert.
1352 * @return the resulting int.
1354 public int toInteger(Object o)
1356 return (int)toNumber(o);
1360 * Convert to number and return it. Returns 0 if cannot be
1361 * converted.
1362 * @param o Lua value to convert.
1363 * @return The resulting number.
1365 public double toNumber(Object o)
1367 SPARE_SLOT.setObject(o);
1368 if (tonumber(SPARE_SLOT, NUMOP))
1370 return NUMOP[0];
1372 return 0;
1376 * Convert to string and return it. If value cannot be converted then
1377 * <code>null</code> is returned. Note that unlike
1378 * <code>lua_tostring</code> this
1379 * does not modify the Lua value.
1380 * @param o Lua value to convert.
1381 * @return The resulting string.
1383 public String toString(Object o)
1385 return vmTostring(o);
1389 * Convert to Lua thread and return it or <code>null</code>.
1390 * @param o Lua value to convert.
1391 * @return The resulting Lua instance.
1393 public Lua toThread(Object o)
1395 if (!(o instanceof Lua))
1397 return null;
1399 return (Lua)o;
1403 * Convert to userdata or <code>null</code>. If value is a {@link
1404 * LuaUserdata} then it is returned, otherwise, <code>null</code> is
1405 * returned.
1406 * @param o Lua value.
1407 * @return value as userdata or <code>null</code>.
1409 public LuaUserdata toUserdata(Object o)
1411 if (o instanceof LuaUserdata)
1413 return (LuaUserdata)o;
1415 return null;
1419 * Type of the Lua value at the specified stack index.
1420 * @param idx stack index to type.
1421 * @return the type, or {@link #TNONE} if there is no value at <var>idx</var>
1423 public int type(int idx)
1425 idx = absIndex(idx);
1426 if (idx < 0)
1428 return TNONE;
1430 return type(stack[idx]);
1433 private int type(Slot s)
1435 if (s.r == NUMBER)
1437 return TNUMBER;
1439 return type(s.r);
1443 * Type of a Lua value.
1444 * @param o the Lua value whose type to return.
1445 * @return the Lua type from an enumeration.
1447 public static int type(Object o)
1449 if (o == NIL)
1451 return TNIL;
1453 else if (o instanceof Double)
1455 return TNUMBER;
1457 else if (o instanceof Boolean)
1459 return TBOOLEAN;
1461 else if (o instanceof String)
1463 return TSTRING;
1465 else if (o instanceof LuaTable)
1467 return TTABLE;
1469 else if (o instanceof LuaFunction || o instanceof LuaJavaCallback)
1471 return TFUNCTION;
1473 else if (o instanceof LuaUserdata)
1475 return TUSERDATA;
1477 else if (o instanceof Lua)
1479 return TTHREAD;
1481 return TNONE;
1485 * Name of type.
1486 * @param type a Lua type from, for example, {@link #type}.
1487 * @return the type's name.
1489 public static String typeName(int type)
1491 if (TNONE == type)
1493 return "no value";
1495 return TYPENAME[type];
1499 * Gets a value from the stack.
1500 * If <var>idx</var> is positive and exceeds
1501 * the size of the stack, {@link #NIL} is returned.
1502 * @param idx the stack index of the value to retrieve.
1503 * @return the Lua value from the stack.
1505 public Object value(int idx)
1507 idx = absIndex(idx);
1508 if (idx < 0)
1510 return NIL;
1512 return stack[idx].asObject();
1516 * Converts primitive boolean into a Lua value.
1517 * @param b the boolean to convert.
1518 * @return the resulting Lua value.
1520 public static Object valueOfBoolean(boolean b)
1522 // If CLDC 1.1 had
1523 // <code>java.lang.Boolean.valueOf(boolean);</code> then I probably
1524 // wouldn't have written this. This does have a small advantage:
1525 // code that uses this method does not need to assume that Lua booleans in
1526 // Jill are represented using Java.lang.Boolean.
1527 if (b)
1529 return Boolean.TRUE;
1531 else
1533 return Boolean.FALSE;
1538 * Converts primitive number into a Lua value.
1539 * @param d the number to convert.
1540 * @return the resulting Lua value.
1542 public static Object valueOfNumber(double d)
1544 // :todo: consider interning "common" numbers, like 0, 1, -1, etc.
1545 return new Double(d);
1549 * Exchange values between different threads.
1550 * @param to destination Lua thread.
1551 * @param n numbers of stack items to move.
1553 public void xmove(Lua to, int n)
1555 if (this == to)
1557 return;
1559 apiChecknelems(n);
1560 // L.apiCheck(from.G() == to.G());
1561 for (int i = 0; i < n; ++i)
1563 to.push(value(-n+i));
1565 pop(n);
1569 * Yields a thread. Should only be called as the return expression
1570 * of a Lua Java function: <code>return L.yield(nresults);</code>.
1571 * A {@link RuntimeException} can also be thrown to yield. If the
1572 * Java code that is executing throws an instance of {@link
1573 * RuntimeException} (direct or indirect) then this causes the Lua
1574 * thread to be suspended, as if <code>L.yield(0);</code> had been
1575 * executed, and the exception is re-thrown to the code that invoked
1576 * {@link #resume}.
1577 * @param nresults Number of results to return to {@link #resume}.
1578 * @return a secret value.
1580 public int yield(int nresults)
1582 if (nCcalls > 0)
1583 gRunerror("attempt to yield across metamethod/Java-call boundary");
1584 base = stackSize - nresults; // protect stack slots below
1585 status = YIELD;
1586 return -1;
1589 // Miscellaneous private functions.
1591 /** Convert from Java API stack index to absolute index.
1592 * @return an index into <code>this.stack</code> or -1 if out of range.
1594 private int absIndex(int idx)
1596 int s = stackSize;
1598 if (idx == 0)
1600 return -1;
1602 if (idx > 0)
1604 if (idx + base > s)
1606 return -1;
1608 return base + idx - 1;
1610 // idx < 0
1611 if (s + idx < base)
1613 return -1;
1615 return s + idx;
1619 * As {@link #absIndex} but does not return -1 for out of range
1620 * indexes. Essential for {@link #insert} because an index equal
1621 * to the size of the stack is valid for that call.
1623 private int absIndexUnclamped(int idx)
1625 if (idx == 0)
1627 return -1;
1629 if (idx > 0)
1631 return base + idx - 1;
1633 // idx < 0
1634 return stackSize + idx;
1638 //////////////////////////////////////////////////////////////////////
1639 // Auxiliary API
1641 // :todo: consider placing in separate class (or macroised) so that we
1642 // can change its definition (to remove the check for example).
1643 private void apiCheck(boolean cond)
1645 if (!cond)
1647 throw new IllegalArgumentException();
1651 private void apiChecknelems(int n)
1653 apiCheck(n <= stackSize - base);
1657 * Checks a general condition and raises error if false.
1658 * @param cond the (evaluated) condition to check.
1659 * @param numarg argument index.
1660 * @param extramsg extra error message to append.
1662 public void argCheck(boolean cond, int numarg, String extramsg)
1664 if (cond)
1666 return;
1668 argRaiseError(numarg, extramsg);
1672 * Raise a general error for an argument.
1673 * @param narg argument index.
1674 * @param extramsg extra message string to append.
1675 * @return never (used idiomatically in <code>return argRaiseError(...)</code>)
1677 public void argRaiseError(int narg, String extramsg)
1679 // :todo: use debug API as per PUC-Rio
1680 if (true)
1682 error("bad argument " + narg + " (" + extramsg + ")");
1687 * Calls a metamethod. Pushes 1 result onto stack if method called.
1688 * @param obj stack index of object whose metamethod to call
1689 * @param event metamethod (event) name.
1690 * @return true if and only if metamethod was found and called.
1692 public boolean callMeta(int obj, String event)
1694 Object o = value(obj);
1695 Object ev = getMetafield(o, event);
1696 if (ev == NIL)
1698 return false;
1700 push(ev);
1701 push(o);
1702 call(1, 1);
1703 return true;
1707 * Checks that an argument is present (can be anything).
1708 * Raises error if not.
1709 * @param narg argument index.
1711 public void checkAny(int narg)
1713 if (type(narg) == TNONE)
1715 argRaiseError(narg, "value expected");
1720 * Checks is a number and returns it as an integer. Raises error if
1721 * not a number.
1722 * @param narg argument index.
1723 * @return the argument as an int.
1725 public int checkInt(int narg)
1727 return (int)checkNumber(narg);
1731 * Checks is a number. Raises error if not a number.
1732 * @param narg argument index.
1733 * @return the argument as a double.
1735 public double checkNumber(int narg)
1737 Object o = value(narg);
1738 double d = toNumber(o);
1739 if (d == 0 && !isNumber(o))
1741 tagError(narg, TNUMBER);
1743 return d;
1747 * Checks that an optional string argument is an element from a set of
1748 * strings. Raises error if not.
1749 * @param narg argument index.
1750 * @param def default string to use if argument not present.
1751 * @param lst the set of strings to match against.
1752 * @return an index into <var>lst</var> specifying the matching string.
1754 public int checkOption(int narg, String def, String[] lst)
1756 String name;
1758 if (def == null)
1760 name = checkString(narg);
1762 else
1764 name = optString(narg, def);
1766 for (int i=0; i<lst.length; ++i)
1768 if (lst[i].equals(name))
1770 return i;
1773 argRaiseError(narg, "invalid option '" + name + "'");
1774 return 0;
1778 * Checks argument is a string and returns it. Raises error if not a
1779 * string.
1780 * @param narg argument index.
1781 * @return the argument as a string.
1783 public String checkString(int narg)
1785 String s = toString(value(narg));
1786 if (s == null)
1788 tagError(narg, TSTRING);
1790 return s;
1794 * Checks the type of an argument, raises error if not matching.
1795 * @param narg argument index.
1796 * @param t typecode (from {@link #type} for example).
1798 public void checkType(int narg, int t)
1800 if (type(narg) != t)
1802 tagError(narg, t);
1807 * Loads and runs the given string.
1808 * @param s the string to run.
1809 * @return a status code, as per {@link #load}.
1811 public int doString(String s)
1813 int status = load(Lua.stringReader(s), s);
1814 if (status == 0)
1816 status = pcall(0, MULTRET, null);
1818 return status;
1821 private int errfile(String what, String fname, Exception e)
1823 push("cannot " + what + " " + fname + ": " + e.toString());
1824 return ERRFILE;
1828 * Equivalent to luaL_findtable. Instead of the table being passed on
1829 * the stack, it is passed as the argument <var>t</var>.
1830 * Likes its PUC-Rio equivalent however, this method leaves a table on
1831 * the Lua stack.
1833 String findTable(LuaTable t, String fname, int szhint)
1835 int e = 0;
1836 int i = 0;
1839 e = fname.indexOf('.', i);
1840 String part;
1841 if (e < 0)
1843 part = fname.substring(i);
1845 else
1847 part = fname.substring(i, e);
1849 Object v = rawGet(t, part);
1850 if (isNil(v)) // no such field?
1852 v = createTable(0,
1853 (e >= 0) ? 1 : szhint); // new table for field
1854 setTable(t, part, v);
1856 else if (!isTable(v)) // field has a non-table value?
1858 return part;
1860 t = (LuaTable)v;
1861 i = e + 1;
1862 } while (e >= 0);
1863 push(t);
1864 return null;
1868 * Get a field (event) from an Lua value's metatable. Returns Lua
1869 * <code>nil</code> if there is either no metatable or no field.
1870 * @param o Lua value to get metafield for.
1871 * @param event name of metafield (event).
1872 * @return the field from the metatable, or nil.
1874 public Object getMetafield(Object o, String event)
1876 LuaTable mt = getMetatable(o);
1877 if (mt == null)
1879 return NIL;
1881 return mt.getlua(event);
1884 boolean isNoneOrNil(int narg)
1886 return type(narg) <= TNIL;
1890 * Loads a Lua chunk from a file. The <var>filename</var> argument is
1891 * used in a call to {@link Class#getResourceAsStream} where
1892 * <code>this</code> is the {@link Lua} instance, thus relative
1893 * pathnames will be relative to the location of the
1894 * <code>Lua.class</code> file. Pushes compiled chunk, or error
1895 * message, onto stack.
1896 * @param filename location of file.
1897 * @return status code, as per {@link #load}.
1899 public int loadFile(String filename)
1901 if (filename == null)
1903 throw new NullPointerException();
1905 InputStream in = getClass().getResourceAsStream(filename);
1906 if (in == null)
1908 return errfile("open", filename, new IOException());
1910 int status = 0;
1913 in.mark(1);
1914 int c = in.read();
1915 if (c == '#') // Unix exec. file?
1917 // :todo: handle this case
1919 in.reset();
1920 status = load(in, "@" + filename);
1922 catch (IOException e)
1924 return errfile("read", filename, e);
1926 return status;
1930 * Loads a Lua chunk from a string. Pushes compiled chunk, or error
1931 * message, onto stack.
1932 * @param s the string to load.
1933 * @param chunkname the name of the chunk.
1934 * @return status code, as per {@link #load}.
1936 public int loadString(String s, String chunkname)
1938 return load(stringReader(s), chunkname);
1942 * Get optional integer argument. Raises error if non-number
1943 * supplied.
1944 * @param narg argument index.
1945 * @param def default value for integer.
1946 * @return an int.
1948 public int optInt(int narg, int def)
1950 if (isNoneOrNil(narg))
1952 return def;
1954 return checkInt(narg);
1958 * Get optional number argument. Raises error if non-number supplied.
1959 * @param narg argument index.
1960 * @param def default value for number.
1961 * @return a double.
1963 public double optNumber(int narg, double def)
1965 if (isNoneOrNil(narg))
1967 return def;
1969 return checkNumber(narg);
1973 * Get optional string argument. Raises error if non-string supplied.
1974 * @param narg argument index.
1975 * @param def default value for string.
1976 * @return a string.
1978 public String optString(int narg, String def)
1980 if (isNoneOrNil(narg))
1982 return def;
1984 return checkString(narg);
1988 * Creates a table in the global namespace and registers it as a loaded
1989 * module.
1990 * @return the new table
1992 LuaTable register(String name)
1994 findTable(getRegistry(), LOADED, 1);
1995 Object loaded = value(-1);
1996 pop(1);
1997 Object t = getField(loaded, name);
1998 if (!isTable(t)) // not found?
2000 // try global variable (and create one if it does not exist)
2001 if (findTable(getGlobals(), name, 0) != null)
2003 error("name conflict for module '" + name + "'");
2005 t = value(-1);
2006 pop(1);
2007 setField(loaded, name, t); // _LOADED[name] = new table
2009 return (LuaTable)t;
2012 private void tagError(int narg, int tag)
2014 typerror(narg, typeName(tag));
2018 * Name of type of value at <var>idx</var>.
2019 * @param idx stack index.
2020 * @return the name of the value's type.
2022 public String typeNameOfIndex(int idx)
2024 return TYPENAME[type(idx)];
2028 * Declare type error in argument.
2029 * @param narg Index of argument.
2030 * @param tname Name of type expected.
2032 public void typerror(int narg, String tname)
2034 argRaiseError(narg, tname + " expected, got " + typeNameOfIndex(narg));
2038 * Return string identifying current position of the control at level
2039 * <var>level</var>.
2040 * @param level specifies the call-stack level.
2041 * @return a description for that level.
2043 public String where(int level)
2045 Debug ar = getStack(level); // check function at level
2046 if (ar != null)
2048 getInfo("Sl", ar); // get info about it
2049 if (ar.currentline() > 0) // is there info?
2051 return ar.shortsrc() + ":" + ar.currentline() + ": ";
2054 return ""; // else, no information available...
2058 * Provide {@link java.io.Reader} interface over a <code>String</code>.
2059 * Equivalent of {@link java.io.StringReader#StringReader} from J2SE.
2060 * The ability to convert a <code>String</code> to a
2061 * <code>Reader</code> is required internally,
2062 * to provide the Lua function <code>loadstring</code>; exposed
2063 * externally as a convenience.
2064 * @param s the string from which to read.
2065 * @return a {@link java.io.Reader} that reads successive chars from <var>s</var>.
2067 public static Reader stringReader(String s)
2069 return new StringReader(s);
2072 //////////////////////////////////////////////////////////////////////
2073 // Debug
2075 // Methods equivalent to debug API. In PUC-Rio most of these are in
2076 // ldebug.c
2078 boolean getInfo(String what, Debug ar)
2080 Object f = null;
2081 CallInfo callinfo = null;
2082 // :todo: complete me
2083 if (ar.ici() > 0) // no tail call?
2085 callinfo = (CallInfo)civ.elementAt(ar.ici());
2086 f = stack[callinfo.function()].r;
2087 //# assert isFunction(f)
2089 boolean status = auxgetinfo(what, ar, f, callinfo);
2090 if (what.indexOf('f') >= 0)
2092 if (f == null)
2094 push(NIL);
2096 else
2098 push(f);
2101 return status;
2105 * Locates function activation at specified call level and returns a
2106 * {@link Debug}
2107 * record for it, or <code>null</code> if level is too high.
2108 * May become public.
2109 * @param level the call level.
2110 * @return a {@link Debug} instance describing the activation record.
2112 Debug getStack(int level)
2114 int ici; // Index of CallInfo
2116 for (ici=civ.size()-1; level > 0 && ici > 0; --ici)
2118 CallInfo ci = (CallInfo)civ.elementAt(ici);
2119 --level;
2120 if (isLua(ci)) // Lua function?
2122 level -= ci.tailcalls(); // skip lost tail calls
2125 if (level == 0 && ici > 0) // level found?
2127 return new Debug(ici);
2129 else if (level < 0) // level is of a lost tail call?
2131 return new Debug(0);
2133 return null;
2137 * Sets the debug hook.
2139 public void setHook(Hook func, int mask, int count)
2141 if (func == null || mask == 0) // turn off hooks?
2143 mask = 0;
2144 func = null;
2146 hook = func;
2147 basehookcount = count;
2148 resethookcount();
2149 hookmask = mask;
2153 * @return true is okay, false otherwise (for example, error).
2155 private boolean auxgetinfo(String what, Debug ar, Object f, CallInfo ci)
2157 boolean status = true;
2158 if (f == null)
2160 // :todo: implement me
2161 return status;
2163 for (int i=0; i<what.length(); ++i)
2165 switch (what.charAt(i))
2167 case 'S':
2168 funcinfo(ar, f);
2169 break;
2170 case 'l':
2171 ar.setCurrentline((ci != null) ? currentline(ci) : -1);
2172 break;
2173 case 'f': // handled by getInfo
2174 break;
2175 // :todo: more cases.
2176 default:
2177 status = false;
2180 return status;
2183 private int currentline(CallInfo ci)
2185 int pc = currentpc(ci);
2186 if (pc < 0)
2188 return -1; // only active Lua functions have current-line info
2190 else
2192 Object faso = stack[ci.function()].r;
2193 LuaFunction f = (LuaFunction)faso;
2194 return f.proto().getline(pc);
2198 private int currentpc(CallInfo ci)
2200 if (!isLua(ci)) // function is not a Lua function?
2202 return -1;
2204 if (ci == ci())
2206 ci.setSavedpc(savedpc);
2208 return pcRel(ci.savedpc());
2211 private void funcinfo(Debug ar, Object cl)
2213 if (cl instanceof LuaJavaCallback)
2215 ar.setSource("=[Java]");
2216 ar.setLinedefined(-1);
2217 ar.setLastlinedefined(-1);
2218 ar.setWhat("Java");
2220 else
2222 Proto p = ((LuaFunction)cl).proto();
2223 ar.setSource(p.source());
2224 ar.setLinedefined(p.linedefined());
2225 ar.setLastlinedefined(p.lastlinedefined());
2226 ar.setWhat(ar.linedefined() == 0 ? "main" : "Lua");
2230 /** Equivalent to macro isLua _and_ f_isLua from lstate.h. */
2231 private boolean isLua(CallInfo callinfo)
2233 Object f = stack[callinfo.function()].r;
2234 return f instanceof LuaFunction;
2237 private static int pcRel(int pc)
2239 return pc - 1;
2242 //////////////////////////////////////////////////////////////////////
2243 // Do
2245 // Methods equivalent to the file ldo.c. Prefixed with d.
2246 // Some of these are in vm* instead.
2249 * Equivalent to luaD_callhook.
2251 private void dCallhook(int event, int line)
2253 Hook hook = this.hook;
2254 if (hook != null && allowhook)
2256 int top = stackSize;
2257 int ci_top = ci().top();
2258 int ici = civ.size() - 1;
2259 if (event == HOOKTAILRET) // not supported yet
2261 ici = 0;
2263 Debug ar = new Debug(ici);
2264 ar.setEvent(event);
2265 ar.setCurrentline(line);
2266 ci().setTop(stackSize);
2267 allowhook = false; // cannot call hooks inside a hook
2268 hook.luaHook(this, ar);
2269 //# assert !allowhook
2270 allowhook = true;
2271 ci().setTop(ci_top);
2272 stacksetsize(top);
2276 private static final String MEMERRMSG = "not enough memory";
2278 /** Equivalent to luaD_seterrorobj. It is valid for oldtop to be
2279 * equal to the current stack size (<code>stackSize</code>).
2280 * {@link #resume} uses this value for oldtop.
2282 private void dSeterrorobj(int errcode, int oldtop)
2284 Object msg = objectAt(stackSize-1);
2285 if (stackSize == oldtop)
2287 stacksetsize(oldtop + 1);
2289 switch (errcode)
2291 case ERRMEM:
2292 stack[oldtop].r = MEMERRMSG;
2293 break;
2295 case ERRERR:
2296 stack[oldtop].r = "error in error handling";
2297 break;
2299 case ERRFILE:
2300 case ERRRUN:
2301 case ERRSYNTAX:
2302 setObjectAt(msg, oldtop);
2303 break;
2305 stacksetsize(oldtop+1);
2308 void dThrow(int status)
2310 throw new LuaError(status);
2314 //////////////////////////////////////////////////////////////////////
2315 // Func
2317 // Methods equivalent to the file lfunc.c. Prefixed with f.
2319 /** Equivalent of luaF_close. All open upvalues referencing stack
2320 * slots level or higher are closed.
2321 * @param level Absolute stack index.
2323 private void fClose(int level)
2325 int i = openupval.size();
2326 while (--i >= 0)
2328 UpVal uv = (UpVal)openupval.elementAt(i);
2329 if (uv.offset() < level)
2331 break;
2333 uv.close();
2335 openupval.setSize(i+1);
2336 return;
2339 private UpVal fFindupval(int idx)
2342 * We search from the end of the Vector towards the beginning,
2343 * looking for an UpVal for the required stack-slot.
2345 int i = openupval.size();
2346 while (--i >= 0)
2348 UpVal uv = (UpVal)openupval.elementAt(i);
2349 if (uv.offset() == idx)
2351 return uv;
2353 if (uv.offset() < idx)
2355 break;
2358 // i points to be position _after_ which we want to insert a new
2359 // UpVal (it's -1 when we want to insert at the beginning).
2360 UpVal uv = new UpVal(idx, stack[idx]);
2361 openupval.insertElementAt(uv, i+1);
2362 return uv;
2366 //////////////////////////////////////////////////////////////////////
2367 // Debug
2369 // Methods equivalent to the file ldebug.c. Prefixed with g.
2371 /** <var>p1</var> and <var>p2</var> are operands to a numeric opcode.
2372 * Corrupts <code>NUMOP[0]</code>.
2373 * There is the possibility of using <var>p1</var> and <var>p2</var> to
2374 * identify (for example) for local variable being used in the
2375 * computation (consider the error message for code like <code>local
2376 * y='a'; return y+1</code> for example). Currently the debug info is
2377 * not used, and this opportunity is wasted (it would require changing
2378 * or overloading gTypeerror).
2380 private void gAritherror(Slot p1, Slot p2)
2382 if (!tonumber(p1, NUMOP))
2384 p2 = p1; // first operand is wrong
2386 gTypeerror(p2, "perform arithmetic on");
2389 /** <var>p1</var> and <var>p2</var> are absolute stack indexes. */
2390 private void gConcaterror(int p1, int p2)
2392 if (stack[p1].r instanceof String)
2394 p1 = p2;
2396 // assert !(p1 instanceof String);
2397 gTypeerror(stack[p1], "concatenate");
2400 boolean gCheckcode(Proto p)
2402 // :todo: implement me.
2403 return true ;
2406 private int gErrormsg(Object message)
2408 push(message);
2409 if (errfunc != null) // is there an error handling function
2411 if (!isFunction(errfunc))
2413 dThrow(ERRERR);
2415 insert(errfunc, getTop()); // push function (under error arg)
2416 vmCall(stackSize-2, 1); // call it
2418 dThrow(ERRRUN);
2419 // NOTREACHED
2420 return 0;
2423 private boolean gOrdererror(Slot p1, Slot p2)
2425 String t1 = typeName(type(p1));
2426 String t2 = typeName(type(p2));
2427 if (t1.charAt(2) == t2.charAt(2))
2429 gRunerror("attempt to compare two " + t1 + "values");
2431 else
2433 gRunerror("attempt to compare " + t1 + " with " + t2);
2435 // NOTREACHED
2436 return false;
2439 void gRunerror(String s)
2441 gErrormsg(s);
2444 private void gTypeerror(Object o, String op)
2446 String t = typeName(type(o));
2447 gRunerror("attempt to " + op + " a " + t + " value");
2450 private void gTypeerror(Slot p, String op)
2452 // :todo: PUC-Rio searches the stack to see if the value (which may
2453 // be a reference to stack cell) is a local variable.
2454 // For now we cop out and just call gTypeerror(Object, String)
2455 gTypeerror(p.asObject(), op);
2459 //////////////////////////////////////////////////////////////////////
2460 // Object
2462 // Methods equivalent to the file lobject.c. Prefixed with o.
2464 private static final int IDSIZE = 60;
2466 * @return a string no longer than IDSIZE.
2468 static String oChunkid(String source)
2470 int len = IDSIZE;
2471 if (source.startsWith("="))
2473 if(source.length() < IDSIZE+1)
2475 return source.substring(1);
2477 else
2479 return source.substring(1, 1+len);
2482 // else "source" or "...source"
2483 if (source.startsWith("@"))
2485 source = source.substring(1);
2486 len -= " '...' ".length();
2487 int l = source.length();
2488 if (l > len)
2490 return "..." + // get last part of file name
2491 source.substring(source.length()-len, source.length());
2493 return source;
2495 // else [string "string"]
2496 int l = source.indexOf('\n');
2497 if (l == -1)
2499 l = source.length();
2501 len -= " [string \"...\"] ".length();
2502 if (l > len)
2504 l = len;
2506 StringBuffer buf = new StringBuffer();
2507 buf.append("[string \"");
2508 buf.append(source.substring(0, l));
2509 if (source.length() > l) // must truncate
2511 buf.append("...");
2513 buf.append("\"]");
2514 return buf.toString();
2518 * Equivalent to luaO_fb2int.
2519 * @see Syntax#oInt2fb
2521 private static int oFb2int(int x)
2523 int e = (x >>> 3) & 31;
2524 if (e == 0)
2526 return x;
2528 return ((x&7)+8) << (e-1);
2531 /** Equivalent to luaO_rawequalObj. */
2532 private static boolean oRawequal(Object a, Object b)
2534 // see also vmEqual
2535 if (NIL == a)
2537 return NIL == b;
2539 // Now a is not null, so a.equals() is a valid call.
2540 // Numbers (Doubles), Booleans, Strings all get compared by value,
2541 // as they should; tables, functions, get compared by identity as
2542 // they should.
2543 return a.equals(b);
2546 /** Equivalent to luaO_str2d. */
2547 private static boolean oStr2d(String s, double[] out)
2549 // :todo: using try/catch may be too slow. In which case we'll have
2550 // to recognise the valid formats first.
2553 out[0] = Double.parseDouble(s);
2554 return true;
2556 catch (NumberFormatException e0_)
2560 // Attempt hexadecimal conversion.
2561 // :todo: using String.trim is not strictly accurate, because it
2562 // trims other ASCII control characters as well as whitespace.
2563 s = s.trim().toUpperCase();
2564 if (s.startsWith("0X"))
2566 s = s.substring(2);
2568 else if (s.startsWith("-0X"))
2570 s = "-" + s.substring(3);
2572 else
2574 return false;
2576 out[0] = Integer.parseInt(s, 16);
2577 return true;
2579 catch (NumberFormatException e1_)
2581 return false;
2587 ////////////////////////////////////////////////////////////////////////
2588 // VM
2590 // Most of the methods in this section are equivalent to the files
2591 // lvm.c and ldo.c from PUC-Rio. They're mostly prefixed with vm as
2592 // well.
2594 private static final int PCRLUA = 0;
2595 private static final int PCRJ = 1;
2596 private static final int PCRYIELD = 2;
2598 // Instruction decomposition.
2600 // There follows a series of methods that extract the various fields
2601 // from a VM instruction. See lopcodes.h from PUC-Rio.
2602 // :todo: Consider replacing with m4 macros (or similar).
2603 // A brief overview of the instruction format:
2604 // Logically an instruction has an opcode (6 bits), op, and up to
2605 // three fields using one of three formats:
2606 // A B C (8 bits, 9 bits, 9 bits)
2607 // A Bx (8 bits, 18 bits)
2608 // A sBx (8 bits, 18 bits signed - excess K)
2609 // Some instructions do not use all the fields (EG OP_UNM only uses A
2610 // and B).
2611 // When packed into a word (an int in Jill) the following layouts are
2612 // used:
2613 // 31 (MSB) 23 22 14 13 6 5 0 (LSB)
2614 // +--------------+--------------+------------+--------+
2615 // | B | C | A | OPCODE |
2616 // +--------------+--------------+------------+--------+
2618 // +--------------+--------------+------------+--------+
2619 // | Bx | A | OPCODE |
2620 // +--------------+--------------+------------+--------+
2622 // +--------------+--------------+------------+--------+
2623 // | sBx | A | OPCODE |
2624 // +--------------+--------------+------------+--------+
2626 static final int NO_REG = 0xff; // SIZE_A == 8, (1 << 8)-1
2628 // Hardwired values for speed.
2629 /** Equivalent of macro GET_OPCODE */
2630 static int OPCODE(int instruction)
2632 // POS_OP == 0 (shift amount)
2633 // SIZE_OP == 6 (opcode width)
2634 return instruction & 0x3f;
2637 /** Equivalent of macro GET_OPCODE */
2638 static int SET_OPCODE(int i, int op)
2640 // POS_OP == 0 (shift amount)
2641 // SIZE_OP == 6 (opcode width)
2642 return (i & ~0x3F) | (op & 0x3F);
2645 /** Equivalent of macro GETARG_A */
2646 static int ARGA(int instruction)
2648 // POS_A == POS_OP + SIZE_OP == 6 (shift amount)
2649 // SIZE_A == 8 (operand width)
2650 return (instruction >>> 6) & 0xff;
2653 static int SETARG_A(int i, int u)
2655 return (i & ~(0xff << 6)) | ((u & 0xff) << 6);
2658 /** Equivalent of macro GETARG_B */
2659 static int ARGB(int instruction)
2661 // POS_B == POS_OP + SIZE_OP + SIZE_A + SIZE_C == 23 (shift amount)
2662 // SIZE_B == 9 (operand width)
2663 /* No mask required as field occupies the most significant bits of a
2664 * 32-bit int. */
2665 return (instruction >>> 23);
2668 static int SETARG_B(int i, int b)
2670 return (i & ~(0x1ff << 23)) | ((b & 0x1ff) << 23);
2673 /** Equivalent of macro GETARG_C */
2674 static int ARGC(int instruction)
2676 // POS_C == POS_OP + SIZE_OP + SIZE_A == 14 (shift amount)
2677 // SIZE_C == 9 (operand width)
2678 return (instruction >>> 14) & 0x1ff;
2681 static int SETARG_C(int i, int c)
2683 return (i & ~(0x1ff << 14)) | ((c & 0x1ff) << 14);
2686 /** Equivalent of macro GETARG_Bx */
2687 static int ARGBx(int instruction)
2689 // POS_Bx = POS_C == 14
2690 // SIZE_Bx == SIZE_C + SIZE_B == 18
2691 /* No mask required as field occupies the most significant bits of a
2692 * 32 bit int. */
2693 return (instruction >>> 14);
2696 static int SETARG_Bx(int i, int bx)
2698 return (i & 0x3fff) | (bx << 14) ;
2702 /** Equivalent of macro GETARG_sBx */
2703 static int ARGsBx(int instruction)
2705 // As ARGBx but with (2**17-1) subtracted.
2706 return (instruction >>> 14) - MAXARG_sBx;
2709 static int SETARG_sBx(int i, int bx)
2711 return (i & 0x3fff) | ((bx+MAXARG_sBx) << 14) ; // CHECK THIS IS RIGHT
2714 static boolean ISK(int field)
2716 // The "is constant" bit position depends on the size of the B and C
2717 // fields (required to be the same width).
2718 // SIZE_B == 9
2719 return field >= 0x100;
2723 * Near equivalent of macros RKB and RKC. Note: non-static as it
2724 * requires stack and base instance members. Stands for "Register or
2725 * Konstant" by the way, it gets value from either the register file
2726 * (stack) or the constant array (k).
2728 private Slot RK(Slot[] k, int field)
2730 if (ISK(field))
2732 return k[field & 0xff];
2734 return stack[base + field];
2737 // CREATE functions are required by FuncState, so default access.
2738 static int CREATE_ABC(int o, int a, int b, int c)
2740 // POS_OP == 0
2741 // POS_A == 6
2742 // POS_B == 23
2743 // POS_C == 14
2744 return o | (a << 6) | (b << 23) | (c << 14);
2747 static int CREATE_ABx(int o, int a, int bc)
2749 // POS_OP == 0
2750 // POS_A == 6
2751 // POS_Bx == POS_C == 14
2752 return o | (a << 6) | (bc << 14);
2755 // opcode enumeration.
2756 // Generated by a script:
2757 // awk -f opcode.awk < lopcodes.h
2758 // and then pasted into here.
2759 // Made default access so that code generation, in FuncState, can see
2760 // the enumeration as well.
2762 static final int OP_MOVE = 0;
2763 static final int OP_LOADK = 1;
2764 static final int OP_LOADBOOL = 2;
2765 static final int OP_LOADNIL = 3;
2766 static final int OP_GETUPVAL = 4;
2767 static final int OP_GETGLOBAL = 5;
2768 static final int OP_GETTABLE = 6;
2769 static final int OP_SETGLOBAL = 7;
2770 static final int OP_SETUPVAL = 8;
2771 static final int OP_SETTABLE = 9;
2772 static final int OP_NEWTABLE = 10;
2773 static final int OP_SELF = 11;
2774 static final int OP_ADD = 12;
2775 static final int OP_SUB = 13;
2776 static final int OP_MUL = 14;
2777 static final int OP_DIV = 15;
2778 static final int OP_MOD = 16;
2779 static final int OP_POW = 17;
2780 static final int OP_UNM = 18;
2781 static final int OP_NOT = 19;
2782 static final int OP_LEN = 20;
2783 static final int OP_CONCAT = 21;
2784 static final int OP_JMP = 22;
2785 static final int OP_EQ = 23;
2786 static final int OP_LT = 24;
2787 static final int OP_LE = 25;
2788 static final int OP_TEST = 26;
2789 static final int OP_TESTSET = 27;
2790 static final int OP_CALL = 28;
2791 static final int OP_TAILCALL = 29;
2792 static final int OP_RETURN = 30;
2793 static final int OP_FORLOOP = 31;
2794 static final int OP_FORPREP = 32;
2795 static final int OP_TFORLOOP = 33;
2796 static final int OP_SETLIST = 34;
2797 static final int OP_CLOSE = 35;
2798 static final int OP_CLOSURE = 36;
2799 static final int OP_VARARG = 37;
2801 // end of instruction decomposition
2803 static final int SIZE_C = 9;
2804 static final int SIZE_B = 9;
2805 static final int SIZE_Bx = SIZE_C + SIZE_B;
2806 static final int SIZE_A = 8;
2808 static final int SIZE_OP = 6;
2810 static final int POS_OP = 0;
2811 static final int POS_A = POS_OP + SIZE_OP;
2812 static final int POS_C = POS_A + SIZE_A;
2813 static final int POS_B = POS_C + SIZE_C;
2814 static final int POS_Bx = POS_C;
2816 static final int MAXARG_Bx = (1<<SIZE_Bx)-1;
2817 static final int MAXARG_sBx = MAXARG_Bx>>1; // `sBx' is signed
2820 static final int MAXARG_A = (1<<SIZE_A)-1;
2821 static final int MAXARG_B = (1<<SIZE_B)-1;
2822 static final int MAXARG_C = (1<<SIZE_C)-1;
2824 /* this bit 1 means constant (0 means register) */
2825 static final int BITRK = 1 << (SIZE_B - 1) ;
2826 static final int MAXINDEXRK = BITRK - 1 ;
2830 * Equivalent of luaD_call.
2831 * @param func absolute stack index of function to call.
2832 * @param r number of required results.
2834 private void vmCall(int func, int r)
2836 ++nCcalls;
2837 if (vmPrecall(func, r) == PCRLUA)
2839 vmExecute(1);
2841 --nCcalls;
2844 /** Equivalent of luaV_concat. */
2845 private void vmConcat(int total, int last)
2849 int top = base + last + 1;
2850 int n = 2; // number of elements handled in this pass (at least 2)
2851 if (!tostring(top-2)|| !tostring(top-1))
2853 if (!call_binTM(stack[top-2], stack[top-1],
2854 stack[top-2], "__concat"))
2856 gConcaterror(top-2, top-1);
2859 else if (((String)stack[top-1].r).length() > 0)
2861 int tl = ((String)stack[top-1].r).length();
2862 for (n = 1; n < total && tostring(top-n-1); ++n)
2864 tl += ((String)stack[top-n-1].r).length();
2865 if (tl < 0)
2867 gRunerror("string length overflow");
2870 StringBuffer buffer = new StringBuffer(tl);
2871 for (int i=n; i>0; i--) // concat all strings
2873 buffer.append(stack[top-i].r);
2875 stack[top-n].r = buffer.toString();
2877 total -= n-1; // got n strings to create 1 new
2878 last -= n-1;
2879 } while (total > 1); // repeat until only 1 result left
2883 * Primitive for testing Lua equality of two values. Equivalent of
2884 * PUC-Rio's <code>equalobj</code> macro.
2885 * In the loosest sense, this is the equivalent of
2886 * <code>luaV_equalval</code>.
2888 private boolean vmEqual(Slot a, Slot b)
2890 // Deal with number case first
2891 if (NUMBER == a.r)
2893 if (NUMBER != b.r)
2895 return false;
2897 return a.d == b.d;
2899 // Now we're only concerned with the .r field.
2900 return vmEqualRef(a.r, b.r);
2904 * Part of {@link #vmEqual}. Compares the reference part of two
2905 * Slot instances. That is, compares two Lua values, as long as
2906 * neither is a number.
2908 private boolean vmEqualRef(Object a, Object b)
2910 if (a.equals(b))
2912 return true;
2914 if (a.getClass() != b.getClass())
2916 return false;
2918 // Same class, but different objects.
2919 if (a instanceof LuaJavaCallback ||
2920 a instanceof LuaTable)
2922 // Resort to metamethods.
2923 Object tm = get_compTM(getMetatable(a), getMetatable(b), "__eq");
2924 if (NIL == tm) // no TM?
2926 return false;
2928 Slot s = new Slot();
2929 callTMres(s, tm, a, b); // call TM
2930 return !isFalse(s.r);
2932 return false;
2936 * Array of numeric operands. Used when converting strings to numbers
2937 * by an arithmetic opcode (ADD, SUB, MUL, DIV, MOD, POW, UNM).
2939 private static final double[] NUMOP = new double[2];
2941 /** The core VM execution engine. */
2942 private void vmExecute(int nexeccalls)
2944 // This labelled while loop is used to simulate the effect of C's
2945 // goto. The end of the while loop is never reached. The beginning
2946 // of the while loop is branched to using a "continue reentry;"
2947 // statement (when a Lua function is called or returns).
2948 reentry:
2949 while (true)
2951 // assert stack[ci.function()].r instanceof LuaFunction;
2952 LuaFunction function = (LuaFunction)stack[ci().function()].r;
2953 Proto proto = function.proto();
2954 int[] code = proto.code();
2955 Slot[] k = proto.constant();
2956 int pc = savedpc;
2958 while (true) // main loop of interpreter
2961 // Where the PUC-Rio code used the Protect macro, this has been
2962 // replaced with "savedpc = pc" and a "// Protect" comment.
2964 // Where the PUC-Rio code used the dojump macro, this has been
2965 // replaced with the equivalent increment of the pc and a
2966 // "//dojump" comment.
2968 int i = code[pc++]; // VM instruction.
2969 // :todo: line hook
2970 if ((hookmask & MASKCOUNT) != 0 && --hookcount == 0)
2972 traceexec(pc);
2973 if (status == YIELD) // did hook yield?
2975 savedpc = pc - 1;
2976 return;
2978 // base = this.base
2981 int a = ARGA(i); // its A field.
2982 Slot rb;
2983 Slot rc;
2985 switch (OPCODE(i))
2987 case OP_MOVE:
2988 stack[base+a].r = stack[base+ARGB(i)].r;
2989 stack[base+a].d = stack[base+ARGB(i)].d;
2990 continue;
2991 case OP_LOADK:
2992 stack[base+a].r = k[ARGBx(i)].r;
2993 stack[base+a].d = k[ARGBx(i)].d;
2994 continue;
2995 case OP_LOADBOOL:
2996 stack[base+a].r = valueOfBoolean(ARGB(i) != 0);
2997 if (ARGC(i) != 0)
2999 ++pc;
3001 continue;
3002 case OP_LOADNIL:
3004 int b = base + ARGB(i);
3007 stack[b--].r = NIL;
3008 } while (b >= base + a);
3009 continue;
3011 case OP_GETUPVAL:
3013 int b = ARGB(i);
3014 // :todo: optimise path
3015 setObjectAt(function.upVal(b).getValue(), base+a);
3016 continue;
3018 case OP_GETGLOBAL:
3019 rb = k[ARGBx(i)];
3020 // assert rb instance of String;
3021 savedpc = pc; // Protect
3022 vmGettable(function.getEnv(), rb, stack[base+a]);
3023 continue;
3024 case OP_GETTABLE:
3026 savedpc = pc; // Protect
3027 Object h = stack[base+ARGB(i)].asObject();
3028 vmGettable(h, RK(k, ARGC(i)), stack[base+a]);
3029 continue;
3031 case OP_SETUPVAL:
3033 UpVal uv = function.upVal(ARGB(i));
3034 uv.setValue(objectAt(base+a));
3035 continue;
3037 case OP_SETGLOBAL:
3038 savedpc = pc; // Protect
3039 // :todo: consider inlining objectAt
3040 vmSettable(function.getEnv(), k[ARGBx(i)],
3041 objectAt(base+a));
3042 continue;
3043 case OP_SETTABLE:
3045 savedpc = pc; // Protect
3046 Object t = stack[base+a].asObject();
3047 vmSettable(t, RK(k, ARGB(i)), RK(k, ARGC(i)).asObject());
3048 continue;
3050 case OP_NEWTABLE:
3052 int b = ARGB(i);
3053 int c = ARGC(i);
3054 stack[base+a].r = new LuaTable(oFb2int(b), oFb2int(c));
3055 continue;
3057 case OP_SELF:
3059 int b = ARGB(i);
3060 rb = stack[base+b];
3061 stack[base+a+1].r = rb.r;
3062 stack[base+a+1].d = rb.d;
3063 savedpc = pc; // Protect
3064 vmGettable(rb.asObject(), RK(k, ARGC(i)), stack[base+a]);
3065 continue;
3067 case OP_ADD:
3068 rb = RK(k, ARGB(i));
3069 rc = RK(k, ARGC(i));
3070 if (rb.r == NUMBER && rc.r == NUMBER)
3072 double sum = rb.d + rc.d;
3073 stack[base+a].d = sum;
3074 stack[base+a].r = NUMBER;
3076 else if (toNumberPair(rb, rc, NUMOP))
3078 double sum = NUMOP[0] + NUMOP[1];
3079 stack[base+a].d = sum;
3080 stack[base+a].r = NUMBER;
3082 else if (!call_binTM(rb, rc, stack[base+a], "__add"))
3084 gAritherror(rb, rc);
3086 continue;
3087 case OP_SUB:
3088 rb = RK(k, ARGB(i));
3089 rc = RK(k, ARGC(i));
3090 if (rb.r == NUMBER && rc.r == NUMBER)
3092 double difference = rb.d - rc.d;
3093 stack[base+a].d = difference;
3094 stack[base+a].r = NUMBER;
3096 else if (toNumberPair(rb, rc, NUMOP))
3098 double difference = NUMOP[0] - NUMOP[1];
3099 stack[base+a].d = difference;
3100 stack[base+a].r = NUMBER;
3102 else if (!call_binTM(rb, rc, stack[base+a], "__sub"))
3104 gAritherror(rb, rc);
3106 continue;
3107 case OP_MUL:
3108 rb = RK(k, ARGB(i));
3109 rc = RK(k, ARGC(i));
3110 if (rb.r == NUMBER && rc.r == NUMBER)
3112 double product = rb.d * rc.d;
3113 stack[base+a].d = product;
3114 stack[base+a].r = NUMBER;
3116 else if (toNumberPair(rb, rc, NUMOP))
3118 double product = NUMOP[0] * NUMOP[1];
3119 stack[base+a].d = product;
3120 stack[base+a].r = NUMBER;
3122 else if (!call_binTM(rb, rc, stack[base+a], "__mul"))
3124 gAritherror(rb, rc);
3126 continue;
3127 case OP_DIV:
3128 rb = RK(k, ARGB(i));
3129 rc = RK(k, ARGC(i));
3130 if (rb.r == NUMBER && rc.r == NUMBER)
3132 double quotient = rb.d / rc.d;
3133 stack[base+a].d = quotient;
3134 stack[base+a].r = NUMBER;
3136 else if (toNumberPair(rb, rc, NUMOP))
3138 double quotient = NUMOP[0] / NUMOP[1];
3139 stack[base+a].d = quotient;
3140 stack[base+a].r = NUMBER;
3142 else if (!call_binTM(rb, rc, stack[base+a], "__div"))
3144 gAritherror(rb, rc);
3146 continue;
3147 case OP_MOD:
3148 rb = RK(k, ARGB(i));
3149 rc = RK(k, ARGC(i));
3150 if (rb.r == NUMBER && rc.r == NUMBER)
3152 double modulus = modulus(rb.d, rc.d);
3153 stack[base+a].d = modulus;
3154 stack[base+a].r = NUMBER;
3156 else if (toNumberPair(rb, rc, NUMOP))
3158 double modulus = modulus(NUMOP[0], NUMOP[1]);
3159 stack[base+a].d = modulus;
3160 stack[base+a].r = NUMBER;
3162 else if (!call_binTM(rb, rc, stack[base+a], "__mod"))
3164 gAritherror(rb, rc);
3166 continue;
3167 case OP_POW:
3168 rb = RK(k, ARGB(i));
3169 rc = RK(k, ARGC(i));
3170 if (rb.r == NUMBER && rc.r == NUMBER)
3172 double result = iNumpow(rb.d, rc.d);
3173 stack[base+a].d = result;
3174 stack[base+a].r = NUMBER;
3176 else if (toNumberPair(rb, rc, NUMOP))
3178 double result = iNumpow(NUMOP[0], NUMOP[1]);
3179 stack[base+a].d = result;
3180 stack[base+a].r = NUMBER;
3182 else if (!call_binTM(rb, rc, stack[base+a], "__pow"))
3184 gAritherror(rb, rc);
3186 continue;
3187 case OP_UNM:
3188 rb = stack[base+ARGB(i)];
3189 if (rb.r == NUMBER)
3191 stack[base+a].d = -rb.d;
3192 stack[base+a].r = NUMBER;
3194 else if (tonumber(rb, NUMOP))
3196 stack[base+a].d = -NUMOP[0];
3197 stack[base+a].r = NUMBER;
3199 else if (!call_binTM(rb, rb, stack[base+a], "__unm"))
3201 gAritherror(rb, rb);
3203 continue;
3204 case OP_NOT:
3206 // All numbers are treated as true, so no need to examine
3207 // the .d field.
3208 Object ra = stack[base+ARGB(i)].r;
3209 stack[base+a].r = valueOfBoolean(isFalse(ra));
3210 continue;
3212 case OP_LEN:
3213 rb = stack[base+ARGB(i)];
3214 if (rb.r instanceof LuaTable)
3216 LuaTable t = (LuaTable)rb.r;
3217 stack[base+a].d = t.getn();
3218 stack[base+a].r = NUMBER;
3219 continue;
3221 else if (rb.r instanceof String)
3223 String s = (String)rb.r;
3224 stack[base+a].d = s.length();
3225 stack[base+a].r = NUMBER;
3226 continue;
3228 savedpc = pc; // Protect
3229 if (!call_binTM(rb, rb, stack[base+a], "__len"))
3231 gTypeerror(rb, "get length of");
3233 continue;
3234 case OP_CONCAT:
3236 int b = ARGB(i);
3237 int c = ARGC(i);
3238 savedpc = pc; // Protect
3239 // :todo: The compiler assumes that all
3240 // stack locations _above_ b end up with junk in them. In
3241 // which case we can improve the speed of vmConcat (by not
3242 // converting each stack slot, but simply using
3243 // StringBuffer.append on whatever is there).
3244 vmConcat(c - b + 1, c);
3245 stack[base+a].r = stack[base+b].r;
3246 stack[base+a].d = stack[base+b].d;
3247 continue;
3249 case OP_JMP:
3250 // dojump
3251 pc += ARGsBx(i);
3252 continue;
3253 case OP_EQ:
3254 rb = RK(k, ARGB(i));
3255 rc = RK(k, ARGC(i));
3256 if (vmEqual(rb, rc) == (a != 0))
3258 // dojump
3259 pc += ARGsBx(code[pc]);
3261 ++pc;
3262 continue;
3263 case OP_LT:
3264 rb = RK(k, ARGB(i));
3265 rc = RK(k, ARGC(i));
3266 savedpc = pc; // Protect
3267 if (vmLessthan(rb, rc) == (a != 0))
3269 // dojump
3270 pc += ARGsBx(code[pc]);
3272 ++pc;
3273 continue;
3274 case OP_LE:
3275 rb = RK(k, ARGB(i));
3276 rc = RK(k, ARGC(i));
3277 savedpc = pc; // Protect
3278 if (vmLessequal(rb, rc) == (a != 0))
3280 // dojump
3281 pc += ARGsBx(code[pc]);
3283 ++pc;
3284 continue;
3285 case OP_TEST:
3286 if (isFalse(stack[base+a].r) != (ARGC(i) != 0))
3288 // dojump
3289 pc += ARGsBx(code[pc]);
3291 ++pc;
3292 continue;
3293 case OP_TESTSET:
3294 rb = stack[base+ARGB(i)];
3295 if (isFalse(rb.r) != (ARGC(i) != 0))
3297 stack[base+a].r = rb.r;
3298 stack[base+a].d = rb.d;
3299 // dojump
3300 pc += ARGsBx(code[pc]);
3302 ++pc;
3303 continue;
3304 case OP_CALL:
3306 int b = ARGB(i);
3307 int nresults = ARGC(i) - 1;
3308 if (b != 0)
3310 stacksetsize(base+a+b);
3312 savedpc = pc;
3313 switch (vmPrecall(base+a, nresults))
3315 case PCRLUA:
3316 nexeccalls++;
3317 continue reentry;
3318 case PCRJ:
3319 // Was Java function called by precall, adjust result
3320 if (nresults >= 0)
3322 stacksetsize(ci().top());
3324 continue;
3325 default:
3326 return; // yield
3329 case OP_TAILCALL:
3331 int b = ARGB(i);
3332 if (b != 0)
3334 stacksetsize(base+a+b);
3336 savedpc = pc;
3337 // assert ARGC(i) - 1 == MULTRET
3338 switch (vmPrecall(base+a, MULTRET))
3340 case PCRLUA:
3342 // tail call: put new frame in place of previous one.
3343 CallInfo ci = (CallInfo)civ.elementAt(civ.size()-2);
3344 int func = ci.function();
3345 CallInfo fci = ci(); // Fresh CallInfo
3346 int pfunc = fci.function();
3347 fClose(ci.base());
3348 base = func + (fci.base() - pfunc);
3349 int aux; // loop index is used after loop ends
3350 for (aux=0; pfunc+aux < stackSize; ++aux)
3352 // move frame down
3353 stack[func+aux].r = stack[pfunc+aux].r;
3354 stack[func+aux].d = stack[pfunc+aux].d;
3356 stacksetsize(func+aux); // correct top
3357 // assert stackSize == base + ((LuaFunction)stack[func]).proto().maxstacksize();
3358 ci.tailcall(base, stackSize);
3359 dec_ci(); // remove new frame.
3360 continue reentry;
3362 case PCRJ: // It was a Java function
3364 continue;
3366 default:
3368 return; // yield
3372 case OP_RETURN:
3374 fClose(base);
3375 int b = ARGB(i);
3376 if (b != 0)
3378 int top = a + b - 1;
3379 stacksetsize(base + top);
3381 savedpc = pc;
3382 // 'adjust' replaces aliased 'b' in PUC-Rio code.
3383 boolean adjust = vmPoscall(base+a);
3384 if (--nexeccalls == 0)
3386 return;
3388 if (adjust)
3390 stacksetsize(ci().top());
3392 continue reentry;
3394 case OP_FORLOOP:
3396 double step = stack[base+a+2].d;
3397 double idx = stack[base+a].d + step;
3398 double limit = stack[base+a+1].d;
3399 if ((0 < step && idx <= limit) ||
3400 (step <= 0 && limit <= idx))
3402 // dojump
3403 pc += ARGsBx(i);
3404 stack[base+a].d = idx; // internal index
3405 stack[base+a].r = NUMBER;
3406 stack[base+a+3].d = idx; // external index
3407 stack[base+a+3].r = NUMBER;
3409 continue;
3411 case OP_FORPREP:
3413 int init = base+a;
3414 int plimit = base+a+1;
3415 int pstep = base+a+2;
3416 savedpc = pc; // next steps may throw errors
3417 if (!tonumber(init))
3419 gRunerror("'for' initial value must be a number");
3421 else if (!tonumber(plimit))
3423 gRunerror("'for' limit must be a number");
3425 else if (!tonumber(pstep))
3427 gRunerror("'for' step must be a number");
3429 double step = stack[pstep].d;
3430 double idx = stack[init].d - step;
3431 stack[init].d = idx;
3432 stack[init].r = NUMBER;
3433 // dojump
3434 pc += ARGsBx(i);
3435 continue;
3437 case OP_TFORLOOP:
3439 int cb = base+a+3; // call base
3440 stack[cb+2].r = stack[base+a+2].r;
3441 stack[cb+2].d = stack[base+a+2].d;
3442 stack[cb+1].r = stack[base+a+1].r;
3443 stack[cb+1].d = stack[base+a+1].d;
3444 stack[cb].r = stack[base+a].r;
3445 stack[cb].d = stack[base+a].d;
3446 stacksetsize(cb+3);
3447 savedpc = pc; // Protect
3448 vmCall(cb, ARGC(i));
3449 stacksetsize(ci().top());
3450 if (NIL != stack[cb].r) // continue loop
3452 stack[cb-1].r = stack[cb].r;
3453 stack[cb-1].d = stack[cb].d;
3454 // dojump
3455 pc += ARGsBx(code[pc]);
3457 ++pc;
3458 continue;
3460 case OP_SETLIST:
3462 int n = ARGB(i);
3463 int c = ARGC(i);
3464 boolean setstack = false;
3465 if (0 == n)
3467 n = (stackSize - (base + a)) - 1;
3468 setstack = true;
3470 if (0 == c)
3472 c = code[pc++];
3474 LuaTable t = (LuaTable)stack[base+a].r;
3475 int last = ((c-1)*LFIELDS_PER_FLUSH) + n;
3476 // :todo: consider expanding space in table
3477 for (; n > 0; n--)
3479 Object val = objectAt(base+a+n);
3480 t.putnum(last--, val);
3482 if (setstack)
3484 stacksetsize(ci().top());
3486 continue;
3488 case OP_CLOSE:
3489 fClose(base+a);
3490 continue;
3491 case OP_CLOSURE:
3493 Proto p = function.proto().proto()[ARGBx(i)];
3494 int nup = p.nups();
3495 UpVal[] up = new UpVal[nup];
3496 for (int j=0; j<nup; j++, pc++)
3498 int in = code[pc];
3499 if (OPCODE(in) == OP_GETUPVAL)
3501 up[j] = function.upVal(ARGB(in));
3503 else
3505 // assert OPCODE(in) == OP_MOVE;
3506 up[j] = fFindupval(base + ARGB(in));
3509 LuaFunction nf = new LuaFunction(p, up, function.getEnv());
3510 stack[base+a].r = nf;
3511 continue;
3513 case OP_VARARG:
3515 int b = ARGB(i)-1;
3516 int n = (base - ci().function()) -
3517 function.proto().numparams() - 1;
3518 if (b == MULTRET)
3520 // :todo: Protect
3521 // :todo: check stack
3522 b = n;
3523 stacksetsize(base+a+n);
3525 for (int j=0; j<b; ++j)
3527 if (j < n)
3529 Slot src = stack[base - n + j];
3530 stack[base+a+j].r = src.r;
3531 stack[base+a+j].d = src.d;
3533 else
3535 stack[base+a+j].r = NIL;
3538 continue;
3540 } /* switch */
3541 } /* while */
3542 } /* reentry: while */
3545 static double iNumpow(double a, double b)
3547 // :todo: this needs proper checking for boundary cases
3548 // EG, is currently wrong for (-0)^2.
3549 boolean invert = b < 0.0 ;
3550 if (invert) b = -b ;
3551 if (a == 0.0)
3552 return invert ? Double.NaN : a ;
3553 double result = 1.0 ;
3554 int ipow = (int) b ;
3555 b -= ipow ;
3556 double t = a ;
3557 while (ipow > 0)
3559 if ((ipow & 1) != 0)
3560 result *= t ;
3561 ipow >>= 1 ;
3562 t = t*t ;
3564 if (b != 0.0) // integer only case, save doing unnecessary work
3566 if (a < 0.0) // doesn't work if a negative (complex result!)
3567 return Double.NaN ;
3568 t = Math.sqrt(a) ;
3569 double half = 0.5 ;
3570 while (b > 0.0)
3572 if (b >= half)
3574 result = result * t ;
3575 b -= half ;
3577 b = b+b ;
3578 t = Math.sqrt(t) ;
3579 if (t == 1.0)
3580 break ;
3583 return invert ? 1.0 / result : result ;
3586 /** Equivalent of luaV_gettable. */
3587 private void vmGettable(Object t, Slot key, Slot val)
3589 Object tm;
3590 for (int loop = 0; loop < MAXTAGLOOP; ++loop)
3592 if (t instanceof LuaTable) // 't' is a table?
3594 LuaTable h = (LuaTable)t;
3595 h.getlua(key, SPARE_SLOT);
3597 if (SPARE_SLOT.r != NIL)
3599 val.r = SPARE_SLOT.r;
3600 val.d = SPARE_SLOT.d;
3601 return;
3603 tm = tagmethod(h, "__index");
3604 if (tm == NIL)
3606 val.r = NIL;
3607 return;
3609 // else will try the tag method
3611 else
3613 tm = tagmethod(t, "__index");
3614 if (tm == NIL)
3615 gTypeerror(t, "index");
3617 if (isFunction(tm))
3619 SPARE_SLOT.setObject(t);
3620 callTMres(val, tm, SPARE_SLOT, key);
3621 return;
3623 t = tm; // else repeat with 'tm'
3625 gRunerror("loop in gettable");
3628 /** Equivalent of luaV_lessthan. */
3629 private boolean vmLessthan(Slot l, Slot r)
3631 if (l.r.getClass() != r.r.getClass())
3633 gOrdererror(l, r);
3635 else if (l.r == NUMBER)
3637 return l.d < r.d;
3639 else if (l.r instanceof String)
3641 // :todo: PUC-Rio use strcoll, maybe we should use something
3642 // equivalent.
3643 return ((String)l.r).compareTo((String)r.r) < 0;
3645 int res = call_orderTM(l, r, "__lt");
3646 if (res >= 0)
3648 return res != 0;
3650 return gOrdererror(l, r);
3653 /** Equivalent of luaV_lessequal. */
3654 private boolean vmLessequal(Slot l, Slot r)
3656 if (l.r.getClass() != r.r.getClass())
3658 gOrdererror(l, r);
3660 else if (l.r == NUMBER)
3662 return l.d <= r.d;
3664 else if (l.r instanceof String)
3666 return ((String)l.r).compareTo((String)r.r) <= 0;
3668 int res = call_orderTM(l, r, "__le"); // first try 'le'
3669 if (res >= 0)
3671 return res != 0;
3673 res = call_orderTM(r, l, "__lt"); // else try 'lt'
3674 if (res >= 0)
3676 return res == 0;
3678 return gOrdererror(l, r);
3682 * Equivalent of luaD_poscall.
3683 * @param firstResult stack index (absolute) of the first result
3685 private boolean vmPoscall(int firstResult)
3687 // :todo: call hook
3688 CallInfo lci; // local copy, for faster access
3689 lci = dec_ci();
3690 // Now (as a result of the dec_ci call), lci is the CallInfo record
3691 // for the current function (the function executing an OP_RETURN
3692 // instruction), and this.ci is the CallInfo record for the function
3693 // we are returning to.
3694 int res = lci.res();
3695 int wanted = lci.nresults(); // Caution: wanted could be == MULTRET
3696 CallInfo cci = ci(); // Continuation CallInfo
3697 base = cci.base();
3698 savedpc = cci.savedpc();
3699 // Move results (and pad with nils to required number if necessary)
3700 int i = wanted;
3701 int top = stackSize;
3702 // The movement is always downwards, so copying from the top-most
3703 // result first is always correct.
3704 while (i != 0 && firstResult < top)
3706 stack[res].r = stack[firstResult].r;
3707 stack[res].d = stack[firstResult].d;
3708 ++res;
3709 ++firstResult;
3710 i--;
3712 if (i > 0)
3714 stacksetsize(res+i);
3716 // :todo: consider using two stacksetsize calls to nil out
3717 // remaining required results.
3718 while (i-- > 0)
3720 stack[res++].r = NIL;
3722 stacksetsize(res);
3723 return wanted != MULTRET;
3727 * Equivalent of LuaD_precall. This method expects that the arguments
3728 * to the function are placed above the function on the stack.
3729 * @param func absolute stack index of the function to call.
3730 * @param r number of results expected.
3732 private int vmPrecall(int func, int r)
3734 Object faso; // Function AS Object
3735 faso = stack[func].r;
3736 if (!isFunction(faso))
3738 faso = tryfuncTM(func);
3740 ci().setSavedpc(savedpc);
3741 if (faso instanceof LuaFunction)
3743 LuaFunction f = (LuaFunction)faso;
3744 Proto p = f.proto();
3745 // :todo: ensure enough stack
3747 if (!p.isVararg())
3749 base = func + 1;
3750 if (stackSize > base + p.numparams())
3752 // trim stack to the argument list
3753 stacksetsize(base + p.numparams());
3756 else
3758 int nargs = (stackSize - func) - 1;
3759 base = adjust_varargs(p, nargs);
3762 int top = base + p.maxstacksize();
3763 inc_ci(func, base, top, r);
3765 savedpc = 0;
3766 // expand stack to the function's max stack size.
3767 stacksetsize(top);
3768 // :todo: implement call hook.
3769 return PCRLUA;
3771 else if (faso instanceof LuaJavaCallback)
3773 LuaJavaCallback fj = (LuaJavaCallback)faso;
3774 // :todo: checkstack (not sure it's necessary)
3775 base = func + 1;
3776 inc_ci(func, base, stackSize+MINSTACK, r);
3777 // :todo: call hook
3778 int n = 99;
3781 n = fj.luaFunction(this);
3783 catch (LuaError e)
3785 throw e;
3787 catch (RuntimeException e)
3789 yield(0);
3790 throw e;
3792 if (n < 0) // yielding?
3794 return PCRYIELD;
3796 else
3798 vmPoscall(stackSize - n);
3799 return PCRJ;
3803 throw new IllegalArgumentException();
3806 /** Equivalent of luaV_settable. */
3807 private void vmSettable(Object t, Slot key, Object val)
3809 for (int loop = 0; loop < MAXTAGLOOP; ++loop)
3811 Object tm;
3812 if (t instanceof LuaTable) // 't' is a table
3814 LuaTable h = (LuaTable)t;
3815 h.getlua(key, SPARE_SLOT);
3816 if (SPARE_SLOT.r != NIL) // result is not nil?
3818 h.putlua(this, key, val);
3819 return;
3821 tm = tagmethod(h, "__newindex");
3822 if (tm == NIL) // or no TM?
3824 h.putlua(this, key, val);
3825 return;
3827 // else will try the tag method
3829 else
3831 tm = tagmethod(t, "__newindex");
3832 if (tm == NIL)
3833 gTypeerror(t, "index");
3835 if (isFunction(tm))
3837 callTM(tm, t, key, val);
3838 return;
3840 t = tm; // else repeat with 'tm'
3842 gRunerror("loop in settable");
3846 * Printf format item used to convert numbers to strings (in {@link
3847 * #vmTostring}). The initial '%' should be not specified.
3849 private static final String NUMBER_FMT = ".14g";
3851 private static String vmTostring(Object o)
3853 if (o instanceof String)
3855 return (String)o;
3857 if (!(o instanceof Double))
3859 return null;
3861 // Convert number to string. PUC-Rio abstracts this operation into
3862 // a macro, lua_number2str. The macro is only invoked from their
3863 // equivalent of this code.
3864 // Formerly this code used Double.toString (and remove any trailing
3865 // ".0") but this does not give an accurate emulation of the PUC-Rio
3866 // behaviour which Intuwave require. So now we use "%.14g" like
3867 // PUC-Rio.
3868 // :todo: consider optimisation of making FormatItem an immutable
3869 // class and keeping a static reference to the required instance
3870 // (which never changes). A possible half-way house would be to
3871 // create a copied instance from an already create prototype
3872 // instance which would be faster than parsing the format string
3873 // each time.
3874 FormatItem f = new FormatItem(null, NUMBER_FMT);
3875 StringBuffer b = new StringBuffer();
3876 Double d = (Double)o;
3877 f.formatFloat(b, d.doubleValue());
3878 return b.toString();
3881 /** Equivalent of adjust_varargs in "ldo.c". */
3882 private int adjust_varargs(Proto p, int actual)
3884 int nfixargs = p.numparams();
3885 for (; actual < nfixargs; ++actual)
3887 stackAdd(NIL);
3889 // PUC-Rio's LUA_COMPAT_VARARG is not supported here.
3891 // Move fixed parameters to final position
3892 int fixed = stackSize - actual; // first fixed argument
3893 int newbase = stackSize; // final position of first argument
3894 for (int i=0; i<nfixargs; ++i)
3896 // :todo: arraycopy?
3897 push(stack[fixed+i]);
3898 stack[fixed+i].r = NIL;
3900 return newbase;
3904 * Does not modify contents of p1 or p2. Modifies contents of res.
3905 * @param p1 left hand operand.
3906 * @param p2 right hand operand.
3907 * @param res absolute stack index of result.
3908 * @return false if no tagmethod, true otherwise
3910 private boolean call_binTM(Slot p1, Slot p2, Slot res, String event)
3912 Object tm = tagmethod(p1.asObject(), event); // try first operand
3913 if (isNil(tm))
3915 tm = tagmethod(p2.asObject(), event); // try second operand
3917 if (!isFunction(tm))
3919 return false;
3921 callTMres(res, tm, p1, p2);
3922 return true;
3926 * @return -1 if no tagmethod, 0 false, 1 true
3928 private int call_orderTM(Slot p1, Slot p2, String event)
3930 Object tm1 = tagmethod(p1.asObject(), event);
3931 if (tm1 == NIL) // not metamethod
3933 return -1;
3935 Object tm2 = tagmethod(p2.asObject(), event);
3936 if (!oRawequal(tm1, tm2)) // different metamethods?
3938 return -1;
3940 Slot s = new Slot();
3941 callTMres(s, tm1, p1, p2);
3942 return isFalse(s.r) ? 0 : 1;
3945 private void callTM(Object f, Object p1, Slot p2, Object p3)
3947 push(f);
3948 push(p1);
3949 push(p2);
3950 push(p3);
3951 vmCall(stackSize-4, 0);
3954 private void callTMres(Slot res, Object f, Slot p1, Slot p2)
3956 push(f);
3957 push(p1);
3958 push(p2);
3959 vmCall(stackSize-3, 1);
3960 res.r = stack[stackSize-1].r;
3961 res.d = stack[stackSize-1].d;
3962 pop(1);
3966 * Overloaded version of callTMres used by {@link #vmEqualRef}.
3967 * Textuall identical, but a different (overloaded) push method is
3968 * invoked.
3970 private void callTMres(Slot res, Object f, Object p1, Object p2)
3972 push(f);
3973 push(p1);
3974 push(p2);
3975 vmCall(stackSize-3, 1);
3976 res.r = stack[stackSize-1].r;
3977 res.d = stack[stackSize-1].d;
3978 pop(1);
3981 private Object get_compTM(LuaTable mt1, LuaTable mt2, String event)
3983 if (mt1 == null)
3985 return NIL;
3987 Object tm1 = mt1.getlua(event);
3988 if (isNil(tm1))
3990 return NIL; // no metamethod
3992 if (mt1 == mt2)
3994 return tm1; // same metatables => same metamethods
3996 if (mt2 == null)
3998 return NIL;
4000 Object tm2 = mt2.getlua(event);
4001 if (isNil(tm2))
4003 return NIL; // no metamethod
4005 if (oRawequal(tm1, tm2)) // same metamethods?
4007 return tm1;
4009 return NIL;
4013 * Gets tagmethod for object.
4014 * @return method or nil.
4016 private Object tagmethod(Object o, String event)
4018 return getMetafield(o, event);
4022 * Computes the result of Lua's modules operator (%). Note that this
4023 * modulus operator does not match Java's %.
4025 private static double modulus(double x, double y)
4027 return x - Math.floor(x/y)*y;
4031 * Changes the stack size, padding with NIL where necessary, and
4032 * allocate a new stack array if necessary.
4034 private void stacksetsize(int n)
4036 // It is absolutely critical that when the stack changes sizes those
4037 // elements that are common to both old and new stack are unchanged.
4039 // First implementation of this simply ensures that the stack array
4040 // has at least the required size number of elements.
4041 // :todo: consider policies where the stack may also shrink.
4042 int old = stackSize;
4043 if (n > stack.length)
4045 int newLength = Math.max(n, 2 * stack.length);
4046 Slot[] newStack = new Slot[newLength];
4047 // Currently the stack only ever grows, so the number of items to
4048 // copy is the length of the old stack.
4049 int toCopy = stack.length;
4050 System.arraycopy(stack, 0, newStack, 0, toCopy);
4051 stack = newStack;
4053 stackSize = n;
4054 // Nilling out. The VM requires that fresh stack slots allocated
4055 // for a new function activation are initialised to nil (which is
4056 // Lua.NIL, which is not Java null).
4057 // There are basically two approaches: nil out when the stack grows,
4058 // or nil out when it shrinks. Nilling out when the stack grows is
4059 // slightly simpler, but nilling out when the stack shrinks means
4060 // that semantic garbage is not retained by the GC.
4061 // We nil out slots when the stack shrinks, but we also need to make
4062 // sure they are nil initially.
4063 // In order to avoid nilling the entire array when we allocate one
4064 // we maintain a stackhighwater which is 1 more than that largest
4065 // stack slot that has been nilled. We use this to nil out stacks
4066 // slow when we grow.
4067 if (n <= old)
4069 // when shrinking
4070 for(int i=n; i<old; ++i)
4072 stack[i].r = NIL;
4075 if (n > stackhighwater)
4077 // when growing above stackhighwater for the first time
4078 for (int i=stackhighwater; i<n; ++i)
4080 stack[i] = new Slot();
4081 stack[i].r = NIL;
4083 stackhighwater = n;
4088 * Pushes a Lua value onto the stack.
4090 private void stackAdd(Object o)
4092 int i = stackSize;
4093 stacksetsize(i+1);
4094 stack[i].setObject(o);
4098 * Copies a slot into a new space in the stack.
4100 private void push(Slot p)
4102 int i = stackSize;
4103 stacksetsize(i+1);
4104 stack[i].r = p.r;
4105 stack[i].d = p.d;
4108 private void stackInsertAt(Object o, int i)
4110 int n = stackSize - i;
4111 stacksetsize(stackSize+1);
4112 // Copy each slot N into its neighbour N+1. Loop proceeds from high
4113 // index slots to lower index slots.
4114 // A loop from n to 1 copies n slots.
4115 for (int j=n; j>=1; --j)
4117 stack[i+j].r = stack[i+j-1].r;
4118 stack[i+j].d = stack[i+j-1].d;
4120 stack[i].setObject(o);
4124 * Equivalent of macro in ldebug.h.
4126 private void resethookcount()
4128 hookcount = basehookcount;
4132 * Equivalent of traceexec in lvm.c.
4134 private void traceexec(int pc)
4136 int mask = hookmask;
4137 savedpc = pc;
4138 if (mask > MASKLINE) // instruction-hook set?
4140 if (hookcount == 0)
4142 resethookcount();
4143 dCallhook(HOOKCOUNT, -1);
4146 // :todo: line hook.
4150 * Convert to number. Returns true if the argument <var>o</var> was
4151 * converted to a number. Converted number is placed in <var>out[0]</var>.
4152 * Returns
4153 * false if the argument <var>o</var> could not be converted to a number.
4154 * Overloaded.
4156 private static boolean tonumber(Slot o, double[] out)
4158 if (o.r == NUMBER)
4160 out[0] = o.d;
4161 return true;
4163 if (!(o.r instanceof String))
4165 return false;
4167 if (oStr2d((String)o.r, out))
4169 return true;
4171 return false;
4175 * Converts a stack slot to number. Returns true if the element at
4176 * the specified stack slot was converted to a number. False
4177 * otherwise. Note that this actually modifies the element stored at
4178 * <var>idx</var> in the stack (in faithful emulation of the PUC-Rio
4179 * code). Corrupts <code>NUMOP[0]</code>. Overloaded.
4180 * @param idx absolute stack slot.
4182 private boolean tonumber(int idx)
4184 if (tonumber(stack[idx], NUMOP))
4186 stack[idx].d = NUMOP[0];
4187 stack[idx].r = NUMBER;
4188 return true;
4190 return false;
4194 * Convert a pair of operands for an arithmetic opcode. Stores
4195 * converted results in <code>out[0]</code> and <code>out[1]</code>.
4196 * @return true if and only if both values converted to number.
4198 private static boolean toNumberPair(Slot x, Slot y, double[] out)
4200 if (tonumber(y, out))
4202 out[1] = out[0];
4203 if (tonumber(x, out))
4205 return true;
4208 return false;
4212 * Convert to string. Returns true if element was number or string
4213 * (the number will have been converted to a string), false otherwise.
4214 * Note this actually modifies the element stored at <var>idx</var> in
4215 * the stack (in faithful emulation of the PUC-Rio code), and when it
4216 * returns <code>true</code>, <code>stack[idx].r instanceof String</code>
4217 * is true.
4219 private boolean tostring(int idx)
4221 // :todo: optimise
4222 Object o = objectAt(idx);
4223 String s = vmTostring(o);
4224 if (s == null)
4226 return false;
4228 stack[idx].r = s;
4229 return true;
4233 * Equivalent to tryfuncTM from ldo.c.
4234 * @param func absolute stack index of the function object.
4236 private Object tryfuncTM(int func)
4238 Object tm = tagmethod(stack[func].asObject(), "__call");
4239 if (!isFunction(tm))
4241 gTypeerror(stack[func], "call");
4243 stackInsertAt(tm, func);
4244 return tm;
4247 /** Lua's is False predicate. */
4248 private boolean isFalse(Object o)
4250 return o == NIL || o == Boolean.FALSE;
4253 /** Make new CallInfo record. */
4254 private CallInfo inc_ci(int func, int baseArg, int top, int nresults)
4256 CallInfo ci = new CallInfo(func, baseArg, top, nresults);
4257 civ.addElement(ci);
4258 return ci;
4261 /** Pop topmost CallInfo record and return it. */
4262 private CallInfo dec_ci()
4264 CallInfo ci = (CallInfo)civ.pop();
4265 return ci;
4268 /** Equivalent to resume_error from ldo.c */
4269 private int resume_error(String msg)
4271 stacksetsize(ci().base());
4272 stackAdd(msg);
4273 return ERRRUN;
4277 * Return the stack element as an Object. Converts double values into
4278 * Double objects.
4279 * @param idx absolute index into stack (0 <= idx < stackSize).
4281 private Object objectAt(int idx)
4283 Object r = stack[idx].r;
4284 if (r != NUMBER)
4286 return r;
4288 return new Double(stack[idx].d);
4292 * Sets the stack element. Double instances are converted to double.
4293 * @param o Object to store.
4294 * @param idx absolute index into stack (0 <= idx < stackSize).
4296 private void setObjectAt(Object o, int idx)
4298 if (o instanceof Double)
4300 stack[idx].r = NUMBER;
4301 stack[idx].d = ((Double)o).doubleValue();
4302 return;
4304 stack[idx].r = o;
4308 * Corresponds to ldump's luaU_dump method, but with data gone and writer
4309 * replaced by OutputStream.
4311 static int uDump(Proto f, OutputStream writer, boolean strip)
4312 throws IOException
4314 DumpState d = new DumpState(new DataOutputStream(writer), strip) ;
4315 d.DumpHeader();
4316 d.DumpFunction(f, null);
4317 d.writer.flush();
4318 return 0; // Any errors result in thrown exceptions.
4323 final class DumpState
4325 DataOutputStream writer;
4326 boolean strip;
4328 DumpState(DataOutputStream writer, boolean strip)
4330 this.writer = writer ;
4331 this.strip = strip ;
4335 //////////////// dumper ////////////////////
4337 void DumpHeader() throws IOException
4340 * In order to make the code more compact the dumper re-uses the
4341 * header defined in Loader.java. It has to fix the endianness byte
4342 * first.
4344 Loader.HEADER[6] = 0;
4345 writer.write(Loader.HEADER) ;
4348 private void DumpInt(int i) throws IOException
4350 writer.writeInt(i) ; // big-endian
4353 private void DumpNumber(double d) throws IOException
4355 writer.writeDouble(d) ; // big-endian
4358 void DumpFunction(Proto f, String p) throws IOException
4360 DumpString((f.source == p || strip) ? null : f.source);
4361 DumpInt(f.linedefined);
4362 DumpInt(f.lastlinedefined);
4363 writer.writeByte(f.nups);
4364 writer.writeByte(f.numparams);
4365 writer.writeBoolean(f.isVararg());
4366 writer.writeByte(f.maxstacksize);
4367 DumpCode(f);
4368 DumpConstants(f);
4369 DumpDebug(f);
4372 private void DumpCode(Proto f) throws IOException
4374 int n = f.sizecode ;
4375 int [] code = f.code ;
4376 DumpInt(n);
4377 for (int i = 0 ; i < n ; i++)
4378 DumpInt(code[i]) ;
4381 private void DumpConstants(Proto f) throws IOException
4383 int n = f.sizek;
4384 Slot[] k = f.k ;
4385 DumpInt(n) ;
4386 for (int i = 0 ; i < n ; i++)
4388 Object o = k[i].r;
4389 if (o == Lua.NIL)
4391 writer.writeByte(Lua.TNIL) ;
4393 else if (o instanceof Boolean)
4395 writer.writeByte(Lua.TBOOLEAN) ;
4396 writer.writeBoolean(((Boolean)o).booleanValue()) ;
4398 else if (o == Lua.NUMBER)
4400 writer.writeByte(Lua.TNUMBER) ;
4401 DumpNumber(k[i].d);
4403 else if (o instanceof String)
4405 writer.writeByte(Lua.TSTRING) ;
4406 DumpString((String)o) ;
4408 else
4410 //# assert false
4413 n = f.sizep ;
4414 DumpInt(n) ;
4415 for (int i = 0 ; i < n ; i++)
4417 Proto subfunc = f.p[i] ;
4418 DumpFunction(subfunc, f.source) ;
4422 private void DumpString(String s) throws IOException
4424 if (s == null)
4426 DumpInt(0);
4428 else
4431 * Strings are dumped by converting to UTF-8 encoding. The MIDP
4432 * 2.0 spec guarantees that this encoding will be supported (see
4433 * page 9 of midp-2_0-fr-spec.pdf). Nonetheless, any
4434 * possible UnsupportedEncodingException is left to be thrown
4435 * (it's a subclass of IOException which is declared to be thrown).
4437 byte [] contents = s.getBytes("UTF-8") ;
4438 int size = contents.length ;
4439 DumpInt(size+1) ;
4440 writer.write(contents, 0, size) ;
4441 writer.writeByte(0) ;
4445 private void DumpDebug(Proto f) throws IOException
4447 if (strip)
4449 DumpInt(0) ;
4450 DumpInt(0) ;
4451 DumpInt(0) ;
4452 return ;
4455 int n = f.sizelineinfo;
4456 DumpInt(n);
4457 for (int i=0; i<n; i++)
4458 DumpInt(f.lineinfo[i]) ;
4460 n = f.sizelocvars;
4461 DumpInt(n);
4462 for (int i=0; i<n; i++)
4464 LocVar locvar = f.locvars[i] ;
4465 DumpString(locvar.varname);
4466 DumpInt(locvar.startpc);
4467 DumpInt(locvar.endpc);
4470 n = f.sizeupvalues;
4471 DumpInt(n);
4472 for (int i=0; i<n; i++)
4473 DumpString(f.upvalues[i]);