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).
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.
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
;
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).
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.
60 * Note that in Jill the stack is used only for passing arguments and
61 * returning results, unlike PUC-Rio.
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.
71 * The methods {@link #push}, {@link #pop}, {@link #value},
72 * {@link #getTop}, {@link #setTop} are used to manipulate the stack.
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
94 private Slot
[] stack
= new Slot
[0];
96 * One more than the highest stack slot that has been written to
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;
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
136 private Vector
<Object
> openupval
= new Vector
<Object
>();
140 boolean allowhook
= true;
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
154 private Object errfunc
;
157 * thread activation 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
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
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
;
205 //////////////////////////////////////////////////////////////////////
209 * Creates a fresh Lua state.
213 this.global
= new LuaTable();
214 this.registry
= new LuaTable();
215 this.metatable
= new LuaTable
[NUM_TAGS
];
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
275 public static final int ERRRUN
= 2;
276 /** Status code, returned from pcall and friends, that indicates
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
291 public static final int ERRFILE
= 6;
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
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
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
)
386 vmConcat(n
, (stackSize
- base
) - 1);
389 else if (n
== 0) // push empty string
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.
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
)
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.
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.
457 public int gc(int what
, int data
)
471 rt
= Runtime
.getRuntime();
472 return (int)((rt
.totalMemory() - rt
.freeMemory()) / 1024);
474 rt
= Runtime
.getRuntime();
475 return (int)((rt
.totalMemory() - rt
.freeMemory()) % 1024);
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
;
495 if (o
instanceof LuaJavaCallback
)
497 // :todo: implement this case.
501 if (o
instanceof LuaUserdata
)
503 LuaUserdata u
= (LuaUserdata
)o
;
506 if (o
instanceof Lua
)
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()
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
)
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();
567 mt
= metatable
[type(o
)];
573 * Gets the registry table.
575 public LuaTable
getRegistry()
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
);
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.
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
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
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()
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
)
669 * Tests that an object is a Lua number or a string convertible to a
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
;
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
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.
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
)
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><</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
);
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,
777 * constructor) and the Lua source is compiled.
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.
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
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
);
834 LuaTable t
= (LuaTable
)o
;
835 Object key
= value(-1);
837 Enumeration
<Object
> e
= t
.keys();
840 if (e
.hasMoreElements())
842 key
= e
.nextElement();
849 while (e
.hasMoreElements())
851 Object k
= e
.nextElement();
854 if (e
.hasMoreElements())
856 key
= e
.nextElement();
864 // protocol error which we could potentially diagnose.
869 * Creates a new empty table and returns it.
870 * @return a fresh table.
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
;
911 if (o
instanceof LuaTable
)
913 LuaTable t
= (LuaTable
)o
;
916 if (o
instanceof Double
)
918 return vmTostring(o
).length();
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
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>.
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
;
954 boolean old_allowhook
= allowhook
;
958 call(nargs
, nresults
);
962 fClose(restoreStack
); // close eventual pending closures
963 dSeterrorobj(e
.errorStatus
, restoreStack
);
964 nCcalls
= oldnCcalls
;
965 civ
.setSize(restoreCi
);
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
);
980 savedpc
= ci
.savedpc();
981 allowhook
= old_allowhook
;
982 errorStatus
= ERRMEM
;
984 errfunc
= old_errfunc
;
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
)
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.
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
)
1033 /** Push nil onto the stack. */
1034 public void pushNil()
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
)
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
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
;
1130 * Register a {@link LuaJavaCallback} as the new value of the global
1132 * @param name the name of the global.
1133 * @param f the LuaJavaCallback to register.
1135 public void register(String name
, LuaJavaCallback 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
)
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;
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
)
1169 else // resuming from previous yield
1171 // assert status == YIELD;
1173 if (!isLua(ci())) // 'common' yield
1175 // finish interrupted execution of 'OP_CALL'
1177 if (vmPoscall(firstArg
)) // complete it...
1178 stacksetsize(ci().top()); // and correct top
1180 else // yielded inside a hook: just continue its execution
1183 vmExecute(civ
.size() - 1);
1187 status
= e
.errorStatus
; // mark thread as 'dead'
1188 dSeterrorobj(e
.errorStatus
, stackSize
);
1189 ci().setTop(stackSize
);
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
1206 LuaTable t
= (LuaTable
)table
;
1208 if (o
instanceof LuaFunction
)
1210 LuaFunction f
= (LuaFunction
)o
;
1214 if (o
instanceof LuaJavaCallback
)
1216 // :todo: implement this case.
1219 if (o
instanceof LuaUserdata
)
1221 LuaUserdata u
= (LuaUserdata
)o
;
1225 if (o
instanceof Lua
)
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
)
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
);
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
)
1309 throw new IllegalArgumentException();
1311 stacksetsize(base
+n
);
1315 * Status of a Lua thread.
1316 * @return 0, an error code, or Lua.YIELD.
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");
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
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
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
))
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
))
1403 * Convert to userdata or <code>null</code>. If value is a {@link
1404 * LuaUserdata} then it is returned, otherwise, <code>null</code> is
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
;
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
);
1430 return type(stack
[idx
]);
1433 private int type(Slot s
)
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
)
1453 else if (o
instanceof Double
)
1457 else if (o
instanceof Boolean
)
1461 else if (o
instanceof String
)
1465 else if (o
instanceof LuaTable
)
1469 else if (o
instanceof LuaFunction
|| o
instanceof LuaJavaCallback
)
1473 else if (o
instanceof LuaUserdata
)
1477 else if (o
instanceof Lua
)
1486 * @param type a Lua type from, for example, {@link #type}.
1487 * @return the type's name.
1489 public static String
typeName(int type
)
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
);
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
)
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.
1529 return Boolean
.TRUE
;
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
)
1560 // L.apiCheck(from.G() == to.G());
1561 for (int i
= 0; i
< n
; ++i
)
1563 to
.push(value(-n
+i
));
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
1577 * @param nresults Number of results to return to {@link #resume}.
1578 * @return a secret value.
1580 public int yield(int nresults
)
1583 gRunerror("attempt to yield across metamethod/Java-call boundary");
1584 base
= stackSize
- nresults
; // protect stack slots below
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
)
1608 return base
+ idx
- 1;
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
)
1631 return base
+ idx
- 1;
1634 return stackSize
+ idx
;
1638 //////////////////////////////////////////////////////////////////////
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
)
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
)
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
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
);
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
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
);
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
)
1760 name
= checkString(narg
);
1764 name
= optString(narg
, def
);
1766 for (int i
=0; i
<lst
.length
; ++i
)
1768 if (lst
[i
].equals(name
))
1773 argRaiseError(narg
, "invalid option '" + name
+ "'");
1778 * Checks argument is a string and returns it. Raises error if not a
1780 * @param narg argument index.
1781 * @return the argument as a string.
1783 public String
checkString(int narg
)
1785 String s
= toString(value(narg
));
1788 tagError(narg
, TSTRING
);
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
)
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
);
1816 status
= pcall(0, MULTRET
, null);
1821 private int errfile(String what
, String fname
, Exception e
)
1823 push("cannot " + what
+ " " + fname
+ ": " + e
.toString());
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
1833 String
findTable(LuaTable t
, String fname
, int szhint
)
1839 e
= fname
.indexOf('.', i
);
1843 part
= fname
.substring(i
);
1847 part
= fname
.substring(i
, e
);
1849 Object v
= rawGet(t
, part
);
1850 if (isNil(v
)) // no such field?
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?
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
);
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
);
1908 return errfile("open", filename
, new IOException());
1915 if (c
== '#') // Unix exec. file?
1917 // :todo: handle this case
1920 status
= load(in
, "@" + filename
);
1922 catch (IOException e
)
1924 return errfile("read", filename
, e
);
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
1944 * @param narg argument index.
1945 * @param def default value for integer.
1948 public int optInt(int narg
, int def
)
1950 if (isNoneOrNil(narg
))
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.
1963 public double optNumber(int narg
, double def
)
1965 if (isNoneOrNil(narg
))
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.
1978 public String
optString(int narg
, String def
)
1980 if (isNoneOrNil(narg
))
1984 return checkString(narg
);
1988 * Creates a table in the global namespace and registers it as a loaded
1990 * @return the new table
1992 LuaTable
register(String name
)
1994 findTable(getRegistry(), LOADED
, 1);
1995 Object loaded
= value(-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
+ "'");
2007 setField(loaded
, name
, t
); // _LOADED[name] = new table
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
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
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 //////////////////////////////////////////////////////////////////////
2075 // Methods equivalent to debug API. In PUC-Rio most of these are in
2078 boolean getInfo(String what
, Debug ar
)
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)
2105 * Locates function activation at specified call level and returns a
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
);
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);
2137 * Sets the debug hook.
2139 public void setHook(Hook func
, int mask
, int count
)
2141 if (func
== null || mask
== 0) // turn off hooks?
2147 basehookcount
= count
;
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;
2160 // :todo: implement me
2163 for (int i
=0; i
<what
.length(); ++i
)
2165 switch (what
.charAt(i
))
2171 ar
.setCurrentline((ci
!= null) ?
currentline(ci
) : -1);
2173 case 'f': // handled by getInfo
2175 // :todo: more cases.
2183 private int currentline(CallInfo ci
)
2185 int pc
= currentpc(ci
);
2188 return -1; // only active Lua functions have current-line info
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?
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);
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
)
2242 //////////////////////////////////////////////////////////////////////
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
2263 Debug ar
= new Debug(ici
);
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
2271 ci().setTop(ci_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);
2292 stack
[oldtop
].r
= MEMERRMSG
;
2296 stack
[oldtop
].r
= "error in error handling";
2302 setObjectAt(msg
, oldtop
);
2305 stacksetsize(oldtop
+1);
2308 void dThrow(int status
)
2310 throw new LuaError(status
);
2314 //////////////////////////////////////////////////////////////////////
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();
2328 UpVal uv
= (UpVal
)openupval
.elementAt(i
);
2329 if (uv
.offset() < level
)
2335 openupval
.setSize(i
+1);
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();
2348 UpVal uv
= (UpVal
)openupval
.elementAt(i
);
2349 if (uv
.offset() == idx
)
2353 if (uv
.offset() < idx
)
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);
2366 //////////////////////////////////////////////////////////////////////
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
)
2396 // assert !(p1 instanceof String);
2397 gTypeerror(stack
[p1
], "concatenate");
2400 boolean gCheckcode(Proto p
)
2402 // :todo: implement me.
2406 private int gErrormsg(Object message
)
2409 if (errfunc
!= null) // is there an error handling function
2411 if (!isFunction(errfunc
))
2415 insert(errfunc
, getTop()); // push function (under error arg)
2416 vmCall(stackSize
-2, 1); // call it
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");
2433 gRunerror("attempt to compare " + t1
+ " with " + t2
);
2439 void gRunerror(String 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 //////////////////////////////////////////////////////////////////////
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
)
2471 if (source
.startsWith("="))
2473 if(source
.length() < IDSIZE
+1)
2475 return source
.substring(1);
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();
2490 return "..." + // get last part of file name
2491 source
.substring(source
.length()-len
, source
.length());
2495 // else [string "string"]
2496 int l
= source
.indexOf('\n');
2499 l
= source
.length();
2501 len
-= " [string \"...\"] ".length();
2506 StringBuffer buf
= new StringBuffer();
2507 buf
.append("[string \"");
2508 buf
.append(source
.substring(0, l
));
2509 if (source
.length() > l
) // must truncate
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;
2528 return ((x
&7)+8) << (e
-1);
2531 /** Equivalent to luaO_rawequalObj. */
2532 private static boolean oRawequal(Object a
, Object 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
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
);
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"))
2568 else if (s
.startsWith("-0X"))
2570 s
= "-" + s
.substring(3);
2576 out
[0] = Integer
.parseInt(s
, 16);
2579 catch (NumberFormatException e1_
)
2587 ////////////////////////////////////////////////////////////////////////
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
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
2611 // When packed into a word (an int in Jill) the following layouts are
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
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
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).
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
)
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
)
2744 return o
| (a
<< 6) | (b
<< 23) | (c
<< 14);
2747 static int CREATE_ABx(int o
, int a
, int bc
)
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
)
2837 if (vmPrecall(func
, r
) == PCRLUA
)
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();
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
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
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
)
2914 if (a
.getClass() != b
.getClass())
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?
2928 Slot s
= new Slot();
2929 callTMres(s
, tm
, a
, b
); // call TM
2930 return !isFalse(s
.r
);
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).
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();
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.
2970 if ((hookmask
& MASKCOUNT
) != 0 && --hookcount
== 0)
2973 if (status
== YIELD
) // did hook yield?
2981 int a
= ARGA(i
); // its A field.
2988 stack
[base
+a
].r
= stack
[base
+ARGB(i
)].r
;
2989 stack
[base
+a
].d
= stack
[base
+ARGB(i
)].d
;
2992 stack
[base
+a
].r
= k
[ARGBx(i
)].r
;
2993 stack
[base
+a
].d
= k
[ARGBx(i
)].d
;
2996 stack
[base
+a
].r
= valueOfBoolean(ARGB(i
) != 0);
3004 int b
= base
+ ARGB(i
);
3008 } while (b
>= base
+ a
);
3014 // :todo: optimise path
3015 setObjectAt(function
.upVal(b
).getValue(), base
+a
);
3020 // assert rb instance of String;
3021 savedpc
= pc
; // Protect
3022 vmGettable(function
.getEnv(), rb
, stack
[base
+a
]);
3026 savedpc
= pc
; // Protect
3027 Object h
= stack
[base
+ARGB(i
)].asObject();
3028 vmGettable(h
, RK(k
, ARGC(i
)), stack
[base
+a
]);
3033 UpVal uv
= function
.upVal(ARGB(i
));
3034 uv
.setValue(objectAt(base
+a
));
3038 savedpc
= pc
; // Protect
3039 // :todo: consider inlining objectAt
3040 vmSettable(function
.getEnv(), k
[ARGBx(i
)],
3045 savedpc
= pc
; // Protect
3046 Object t
= stack
[base
+a
].asObject();
3047 vmSettable(t
, RK(k
, ARGB(i
)), RK(k
, ARGC(i
)).asObject());
3054 stack
[base
+a
].r
= new LuaTable(oFb2int(b
), oFb2int(c
));
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
]);
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
);
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
);
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
);
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
);
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
);
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
);
3188 rb
= stack
[base
+ARGB(i
)];
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
);
3206 // All numbers are treated as true, so no need to examine
3208 Object ra
= stack
[base
+ARGB(i
)].r
;
3209 stack
[base
+a
].r
= valueOfBoolean(isFalse(ra
));
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
;
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
;
3228 savedpc
= pc
; // Protect
3229 if (!call_binTM(rb
, rb
, stack
[base
+a
], "__len"))
3231 gTypeerror(rb
, "get length of");
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
;
3254 rb
= RK(k
, ARGB(i
));
3255 rc
= RK(k
, ARGC(i
));
3256 if (vmEqual(rb
, rc
) == (a
!= 0))
3259 pc
+= ARGsBx(code
[pc
]);
3264 rb
= RK(k
, ARGB(i
));
3265 rc
= RK(k
, ARGC(i
));
3266 savedpc
= pc
; // Protect
3267 if (vmLessthan(rb
, rc
) == (a
!= 0))
3270 pc
+= ARGsBx(code
[pc
]);
3275 rb
= RK(k
, ARGB(i
));
3276 rc
= RK(k
, ARGC(i
));
3277 savedpc
= pc
; // Protect
3278 if (vmLessequal(rb
, rc
) == (a
!= 0))
3281 pc
+= ARGsBx(code
[pc
]);
3286 if (isFalse(stack
[base
+a
].r
) != (ARGC(i
) != 0))
3289 pc
+= ARGsBx(code
[pc
]);
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
;
3300 pc
+= ARGsBx(code
[pc
]);
3307 int nresults
= ARGC(i
) - 1;
3310 stacksetsize(base
+a
+b
);
3313 switch (vmPrecall(base
+a
, nresults
))
3319 // Was Java function called by precall, adjust result
3322 stacksetsize(ci().top());
3334 stacksetsize(base
+a
+b
);
3337 // assert ARGC(i) - 1 == MULTRET
3338 switch (vmPrecall(base
+a
, MULTRET
))
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();
3348 base
= func
+ (fci
.base() - pfunc
);
3349 int aux
; // loop index is used after loop ends
3350 for (aux
=0; pfunc
+aux
< stackSize
; ++aux
)
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.
3362 case PCRJ
: // It was a Java function
3378 int top
= a
+ b
- 1;
3379 stacksetsize(base
+ top
);
3382 // 'adjust' replaces aliased 'b' in PUC-Rio code.
3383 boolean adjust
= vmPoscall(base
+a
);
3384 if (--nexeccalls
== 0)
3390 stacksetsize(ci().top());
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
))
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
;
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
;
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
;
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
;
3455 pc
+= ARGsBx(code
[pc
]);
3464 boolean setstack
= false;
3467 n
= (stackSize
- (base
+ a
)) - 1;
3474 LuaTable t
= (LuaTable
)stack
[base
+a
].r
;
3475 int last
= ((c
-1)*LFIELDS_PER_FLUSH
) + n
;
3476 // :todo: consider expanding space in table
3479 Object val
= objectAt(base
+a
+n
);
3480 t
.putnum(last
--, val
);
3484 stacksetsize(ci().top());
3493 Proto p
= function
.proto().proto()[ARGBx(i
)];
3495 UpVal
[] up
= new UpVal
[nup
];
3496 for (int j
=0; j
<nup
; j
++, pc
++)
3499 if (OPCODE(in
) == OP_GETUPVAL
)
3501 up
[j
] = function
.upVal(ARGB(in
));
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
;
3516 int n
= (base
- ci().function()) -
3517 function
.proto().numparams() - 1;
3521 // :todo: check stack
3523 stacksetsize(base
+a
+n
);
3525 for (int j
=0; j
<b
; ++j
)
3529 Slot src
= stack
[base
- n
+ j
];
3530 stack
[base
+a
+j
].r
= src
.r
;
3531 stack
[base
+a
+j
].d
= src
.d
;
3535 stack
[base
+a
+j
].r
= NIL
;
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
;
3552 return invert ? Double
.NaN
: a
;
3553 double result
= 1.0 ;
3554 int ipow
= (int) b
;
3559 if ((ipow
& 1) != 0)
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!)
3574 result
= result
* t
;
3583 return invert ?
1.0 / result
: result
;
3586 /** Equivalent of luaV_gettable. */
3587 private void vmGettable(Object t
, Slot key
, Slot val
)
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
;
3603 tm
= tagmethod(h
, "__index");
3609 // else will try the tag method
3613 tm
= tagmethod(t
, "__index");
3615 gTypeerror(t
, "index");
3619 SPARE_SLOT
.setObject(t
);
3620 callTMres(val
, tm
, SPARE_SLOT
, key
);
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())
3635 else if (l
.r
== NUMBER
)
3639 else if (l
.r
instanceof String
)
3641 // :todo: PUC-Rio use strcoll, maybe we should use something
3643 return ((String
)l
.r
).compareTo((String
)r
.r
) < 0;
3645 int res
= call_orderTM(l
, r
, "__lt");
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())
3660 else if (l
.r
== NUMBER
)
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'
3673 res
= call_orderTM(r
, l
, "__lt"); // else try 'lt'
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
)
3688 CallInfo lci
; // local copy, for faster access
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
3698 savedpc
= cci
.savedpc();
3699 // Move results (and pad with nils to required number if necessary)
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
;
3714 stacksetsize(res
+i
);
3716 // :todo: consider using two stacksetsize calls to nil out
3717 // remaining required results.
3720 stack
[res
++].r
= NIL
;
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
3750 if (stackSize
> base
+ p
.numparams())
3752 // trim stack to the argument list
3753 stacksetsize(base
+ p
.numparams());
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
);
3766 // expand stack to the function's max stack size.
3768 // :todo: implement call hook.
3771 else if (faso
instanceof LuaJavaCallback
)
3773 LuaJavaCallback fj
= (LuaJavaCallback
)faso
;
3774 // :todo: checkstack (not sure it's necessary)
3776 inc_ci(func
, base
, stackSize
+MINSTACK
, r
);
3781 n
= fj
.luaFunction(this);
3787 catch (RuntimeException e
)
3792 if (n
< 0) // yielding?
3798 vmPoscall(stackSize
- n
);
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
)
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
);
3821 tm
= tagmethod(h
, "__newindex");
3822 if (tm
== NIL
) // or no TM?
3824 h
.putlua(this, key
, val
);
3827 // else will try the tag method
3831 tm
= tagmethod(t
, "__newindex");
3833 gTypeerror(t
, "index");
3837 callTM(tm
, t
, key
, val
);
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
)
3857 if (!(o
instanceof Double
))
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
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
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
)
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
;
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
3915 tm
= tagmethod(p2
.asObject(), event
); // try second operand
3917 if (!isFunction(tm
))
3921 callTMres(res
, tm
, p1
, p2
);
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
3935 Object tm2
= tagmethod(p2
.asObject(), event
);
3936 if (!oRawequal(tm1
, tm2
)) // different metamethods?
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
)
3951 vmCall(stackSize
-4, 0);
3954 private void callTMres(Slot res
, Object f
, Slot p1
, Slot p2
)
3959 vmCall(stackSize
-3, 1);
3960 res
.r
= stack
[stackSize
-1].r
;
3961 res
.d
= stack
[stackSize
-1].d
;
3966 * Overloaded version of callTMres used by {@link #vmEqualRef}.
3967 * Textuall identical, but a different (overloaded) push method is
3970 private void callTMres(Slot res
, Object f
, Object p1
, Object p2
)
3975 vmCall(stackSize
-3, 1);
3976 res
.r
= stack
[stackSize
-1].r
;
3977 res
.d
= stack
[stackSize
-1].d
;
3981 private Object
get_compTM(LuaTable mt1
, LuaTable mt2
, String event
)
3987 Object tm1
= mt1
.getlua(event
);
3990 return NIL
; // no metamethod
3994 return tm1
; // same metatables => same metamethods
4000 Object tm2
= mt2
.getlua(event
);
4003 return NIL
; // no metamethod
4005 if (oRawequal(tm1
, tm2
)) // same metamethods?
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
);
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.
4070 for(int i
=n
; i
<old
; ++i
)
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();
4088 * Pushes a Lua value onto the stack.
4090 private void stackAdd(Object o
)
4094 stack
[i
].setObject(o
);
4098 * Copies a slot into a new space in the stack.
4100 private void push(Slot p
)
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
;
4138 if (mask
> MASKLINE
) // instruction-hook set?
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>.
4153 * false if the argument <var>o</var> could not be converted to a number.
4156 private static boolean tonumber(Slot o
, double[] out
)
4163 if (!(o
.r
instanceof String
))
4167 if (oStr2d((String
)o
.r
, out
))
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
;
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
))
4203 if (tonumber(x
, out
))
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>
4219 private boolean tostring(int idx
)
4222 Object o
= objectAt(idx
);
4223 String s
= vmTostring(o
);
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
);
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
);
4261 /** Pop topmost CallInfo record and return it. */
4262 private CallInfo
dec_ci()
4264 CallInfo ci
= (CallInfo
)civ
.pop();
4268 /** Equivalent to resume_error from ldo.c */
4269 private int resume_error(String msg
)
4271 stacksetsize(ci().base());
4277 * Return the stack element as an Object. Converts double values into
4279 * @param idx absolute index into stack (0 <= idx < stackSize).
4281 private Object
objectAt(int idx
)
4283 Object r
= stack
[idx
].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();
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
)
4314 DumpState d
= new DumpState(new DataOutputStream(writer
), strip
) ;
4316 d
.DumpFunction(f
, null);
4318 return 0; // Any errors result in thrown exceptions.
4323 final class DumpState
4325 DataOutputStream writer
;
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
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
);
4372 private void DumpCode(Proto f
) throws IOException
4374 int n
= f
.sizecode
;
4375 int [] code
= f
.code
;
4377 for (int i
= 0 ; i
< n
; i
++)
4381 private void DumpConstants(Proto f
) throws IOException
4386 for (int i
= 0 ; i
< n
; i
++)
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
) ;
4403 else if (o
instanceof String
)
4405 writer
.writeByte(Lua
.TSTRING
) ;
4406 DumpString((String
)o
) ;
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
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
;
4440 writer
.write(contents
, 0, size
) ;
4441 writer
.writeByte(0) ;
4445 private void DumpDebug(Proto f
) throws IOException
4455 int n
= f
.sizelineinfo
;
4457 for (int i
=0; i
<n
; i
++)
4458 DumpInt(f
.lineinfo
[i
]) ;
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
);
4472 for (int i
=0; i
<n
; i
++)
4473 DumpString(f
.upvalues
[i
]);