root/trunk/lua/state.d

Revision 314, 85.6 kB (checked in by xammy, 3 weeks ago)

Bugfixes for LuaLib (package library, thread destruction)

Line 
1 /*******************************************************************************
2
3     copyright:      Copyright (c) 2008 Matthias Walter. All rights reserved
4
5     authors:        Matthias Walter, Andreas Hollandt, Clemens Hofreither
6
7 *******************************************************************************/
8
9 module lua.state;
10
11 private import lua.lua, lua.lualib, lua.lauxlib;
12 private import lua.buffer, lua.mixins, lua.error, lua.data, lua.utils;
13
14 version (Tango)
15 {
16     private import tango.stdc.stdio : fputs, stdout;
17 }
18
19 version (Phobos)
20 {
21     private import std.string : fputs, stdout;
22 }
23
24 /*******************************************************************************
25
26     LuaStandardLibraries defines Constants for the different modules, which
27     add basic functionality to a state. They can be OR'ed together to combine
28     them.
29
30     Use it as an argument to LuaState.openLibraries to select them.
31
32 *******************************************************************************/
33
34 public enum LuaStandardLibraries : int
35 {
36     BASE = 0,
37     TABLE = 1,
38     STRING = 2,
39     MATH = 4,
40     OS = 8,
41     IO = 16,
42     DEBUG = 32,
43     PACKAGE = 64,
44     SAFE = BASE | TABLE | STRING | MATH | OS | PACKAGE,
45     ALL = BASE | TABLE | STRING | MATH | OS | PACKAGE | IO | DEBUG
46 }
47
48 /*******************************************************************************
49
50     LuaType defines Constants for the different Lua-internal types.
51
52 *******************************************************************************/
53
54 public enum LuaType : int
55 {
56     NONE = LUA_TNONE,
57     NIL = LUA_TNIL,
58     NUMBER = LUA_TNUMBER,
59     BOOL = LUA_TBOOLEAN,
60     STRING = LUA_TSTRING,
61     TABLE = LUA_TTABLE,
62     FUNCTION = LUA_TFUNCTION,
63     USERDATA = LUA_TUSERDATA,
64     THREAD = LUA_TTHREAD,
65     LIGHTUSERDATA = LUA_TLIGHTUSERDATA
66 }
67
68 /*******************************************************************************
69
70     LuaGarbageCollectorCommand defines Commands for the LuaState.gc function,
71     which controls the garbage collector of a LuaState.
72
73 *******************************************************************************/
74
75 public enum LuaGarbageCollectorCommand : int
76 {
77     STOP = LUA_GCSTOP,
78     RESTART = LUA_GCRESTART,
79     COLLECT = LUA_GCCOLLECT,
80     COUNT = LUA_GCCOUNT,
81     STEP = LUA_GCSTEP,
82     SET_PAUSE = LUA_GCSETPAUSE,
83     SET_STEP_MULTIPLIER = LUA_GCSETSTEPMUL
84 }
85
86 /// Type of Function with C-linkage which can interface to Lua directly.
87
88 alias lua_CFunction LuaCFunction;
89
90 /// Type of Integers in Lua
91
92 alias lua_Integer LuaInteger;
93
94 /// Type of Floats in Lua
95
96 alias lua_Number LuaNumber;
97
98 /// Registration struct for registering C-linkage functions with Lua
99
100 struct LuaRegistry
101 {
102     char[] name;
103     LuaCFunction cfunction;
104     int category;
105 }
106
107 /// Delegate type for redirecting Lua's stdout to the D host program.
108
109 alias void delegate (char[] output) LuaPrint;
110
111 /*******************************************************************************
112
113     LuaState wraps a Lua state which keeps the whole state of the Lua
114     interpreter. It is thread-safe, as there are no global variables in the
115     C library and no unsynchronized static variables in the D wrapper.
116
117     Nearly all of the standard Lua functions are wrapped or reimplemented
118     somehow. There are the following exceptions:
119
120     The panic function cannot be changed, which is due to the longjmp
121     implementation of the Lua library. Thus you should always use protected
122     calls as an initial call to Lua code. If you still want the application
123     to panic then, you simply do not catch the exceptions thrown by this
124     call, which should terminate your application. Thus, there is no
125     wrapper for the lua_atpanic function.
126
127     Also, you cannot set a user-supplied allocation function. As Lua has
128     its own garbage collector and all other C variables are directly
129     freed by the wrapper classes, this is unnecessary. Thus, there is also
130     no wrapper for lua_setallocf and lua_getallocf.
131
132     Some string manipulation/construction routines are not wrapped, because
133     this is more easily done in D directly or using the standard library of
134     your choice. This has impact on lua_pushfstring, lua_pushvfstring and
135     luaL_gsub.
136
137 *******************************************************************************/
138
139 class LuaState
140 {
141     /// Wrapper Lua state
142     private lua_State* state_;
143
144     /// Writer delegate, the Lua stdout
145     private LuaPrint write_;
146    
147     /// Whether the LuaState was created as a sub-thread of another state by calling newThread().
148     private bool is_thread_state_;
149
150     /// Constant to pass instead of a number of expected results, if this number is unknown.
151     public const int MULTIPLE_RETURN_VALUES = LUA_MULTRET;
152
153     /*******************************************************************************
154
155         Constructs a state with an optional printer delegate. If the latter is
156         null, stdout is not redirected.
157
158         Params:
159         write = Optional printer delegate.
160
161         Remarks:
162         Replaces lua_open, lua_newstate and luaL_newstate.
163
164      *******************************************************************************/
165
166     public this (LuaPrint write = null)
167     {
168         this.state_ = lua_open ();
169         this.write_ = (write is null) ? &writeDefault : write;
170
171         openLibraries (LuaStandardLibraries.BASE);
172
173         LuaState.states[this.state_] = this;
174     }
175
176     /*******************************************************************************
177
178         Internal Constructor for Lua thread creation.
179
180         Params:
181         write = Printer delegate
182         state = Lua state
183
184     *******************************************************************************/
185
186     private this (LuaPrint write, lua_State* state)
187     {
188         this.write_ = write;
189         this.state_ = state;
190
191         LuaState.states[this.state_] = this;
192     }
193
194     /*******************************************************************************
195
196         Destructor
197
198         Remarks:
199         Replaces lua_close.
200
201     *******************************************************************************/
202
203     private ~this ()
204     {
205         LuaState.states.remove (this.state_);
206
207         // bugfix by Clemens:
208         // states which represent child threads may not be destroyed
209         if (!is_thread_state_)
210         {
211             lua_close (this.state_);
212         }
213     }
214
215     /*******************************************************************************
216
217         Returns:
218         The internal wrapped lua_State object.
219
220         Remarks:
221         If you really need to use this function, please contact the author. For
222         most functionality there should be a corresponding wrapper function.
223
224     *******************************************************************************/
225
226     public lua_State* state ()
227     {
228         return this.state_;
229     }
230
231     /*******************************************************************************
232
233         Opens the specified standard libraries and adds their functionality to this state.
234         See the LuaStandardLibraries enum for possible choices.
235
236         Params:
237         categories = choice of standard libraries
238
239         Remarks:
240         Replaces luaL_openlibs.
241
242     *******************************************************************************/
243
244     public LuaState openLibraries (LuaStandardLibraries categories = LuaStandardLibraries.ALL)
245     {
246         static LuaRegistry[] lualibs = [
247              { "", &luaopen_base, LuaStandardLibraries.BASE },
248              { LUA_TABLIBNAME, &luaopen_table, LuaStandardLibraries.TABLE },
249              { LUA_IOLIBNAME, &luaopen_io, LuaStandardLibraries.IO },
250              { LUA_OSLIBNAME, &luaopen_os, LuaStandardLibraries.OS },
251              { LUA_STRLIBNAME, &luaopen_string, LuaStandardLibraries.STRING },
252              { LUA_MATHLIBNAME, &luaopen_math, LuaStandardLibraries.MATH },
253              { LUA_DBLIBNAME, &luaopen_debug, LuaStandardLibraries.DEBUG },
254              { LUA_LOADLIBNAME, &luaopen_package, LuaStandardLibraries.PACKAGE }
255         ];
256
257         openLibraries (lualibs, categories);
258
259         registerFunction ("print", &print);
260
261         return this;
262     }
263
264     /*******************************************************************************
265
266         Opens all of the given libraries, which match the given categories bits,
267         and adds their functionality to this state.
268
269         Params:
270         libraries = Array of possible libraries
271         categories = Choice to open. Default is -1, which opens all.
272
273     *******************************************************************************/
274
275     public LuaState openLibraries (LuaRegistry[] libraries, int categories = -1)
276     {
277         foreach (LuaRegistry reg; libraries)
278         {
279             if (reg.category == 0 || (reg.category & categories) != 0)
280             {
281                 openLibrary (reg.name, reg.cfunction);
282             }
283         }
284         return this;
285     }
286
287     /*******************************************************************************
288
289         Opens one library, adding its functionality to this state. The
290         registration function must take the library name as its only
291         argument.
292
293         Params:
294         library_name = Name of the library
295         registration_function = C-linkage function to call for registration
296
297     ******************************************************************************/
298
299     public LuaState openLibrary (char[] library_name, LuaCFunction registration_function)
300     {
301         pushCFunction (registration_function);
302         pushString (library_name);
303         call (false, 1, 0);
304
305         return this;
306     }
307
308     /*******************************************************************************
309
310         Internal method to pass the given data to the writer delegate.
311
312         Params:
313         data = Output to write.
314
315     ******************************************************************************/
316
317     private void write (char[] data)
318     {
319         this.write_ (data);
320     }
321
322     /*******************************************************************************
323
324         Standard writer function, if none is specified in Constructor.
325
326         Params:
327         output = Output to write.
328
329     ******************************************************************************/
330
331     private void writeDefault (char[] output)
332     {
333         fputs (toStringz (output), stdout);
334     }
335
336     /*******************************************************************************
337
338         Calls the C function with only one element in its stack, a LightUserdata,
339         specified as an argument. It does not change the stack. All values
340         returned by the function are discarded. For behavior on errors and the
341         description of proctection schemes, see the other call method.
342         
343         Params:
344         protection = whether this is a protected call.
345         cfunction = Pointer to a C function.
346         userdata = Pointer to C data.
347         
348         Remarks:
349         Replaces lua_cpcall.
350
351     ******************************************************************************/
352
353     public LuaState call (bool protection, LuaCFunction cfunction, void* userdata)
354     {
355         pushCFunction (cfunction);
356         pushLightUserdata (userdata);
357         call (protection, 1, 0);
358
359         return this;
360     }
361
362     /*******************************************************************************
363
364         Method to call a Lua function, using the following protocol:
365
366         First, the function to be called is pushed onto the stack; then, the
367         arguments to the function are pushed in direct order; that is, the first
368         argument is pushed first. Finally you call this method with
369         the number of arguments that you pushed onto the stack and the expected
370         number of return values. All arguments and the function value are popped
371         from the stack when the function is called. The function results are
372         pushed onto the stack when the function returns. The number of results is
373         adjusted to the expected number, unless the latter is
374         MULTIPLE_RETURN_VALUES, which is the default. In this case, all results
375         from the function are pushed. Lua takes care that the returned values fit
376         into the stack space. The function results are pushed onto the stack in
377         direct order (the first result is pushed first), so that after the call
378         the last result is on the top of the stack.
379
380         There are two different protection schemes, which define behavior on
381         errors:
382
383         Protected calls catch errors inside the called function (and all further
384         called functions) and throw according exceptions. Lua errors result in
385         LuaCodeExceptions and exceptions in D routines which are correctly wrapped
386         via the lua mixins result in LuaForwardExceptions.
387
388         Unprotected calls do not catch errors, but quietly propagate them to the
389         next protected call in the call stack. If there is no such protected call,
390         the application panics, exiting with status 1 and an error message.
391
392         The author of this library suggests the following rules for protection:
393
394         1. If the called routine and its subroutines are really safe,
395            use an unprotected call.
396         2. If this call happens to be called as the first function on the Lua
397            call stack, use a protected call.
398         3. If this is not the first function on the call stack (e.g. in a library
399            function called by some Lua code, which is called by a protected call)
400            you have the choice. Unprotected calls should be slightly faster, but
401            on error, a protected call would add one LuaForwardException to the
402            exception stack, which may help to identify error sources.
403
404         Params:
405         protection = whether this is a protected call.
406         arguments = number of function arguments on the stack. Default is 0
407         results = expected number of return values. Default is a variable number.
408
409         Remarks:
410         Replaces lua_call and lua_pcall.
411
412     ******************************************************************************/
413
414     public LuaState call (bool protection, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES)
415     {
416         if (protection)
417         {
418             int errors = lua_pcall (this.state_, arguments, results, 0);
419             if (errors != 0)
420             {
421                 char[] error = popString ();
422
423                 // parse the error string to extract the address of the exception
424                 char[] pointer_string = null;
425                 for (int start = error.length-6; start >= 0; start--)
426                 {
427                     if (error[start .. start + 4] == "LFE=")
428                     {
429                         for (int end = start+5; end < error.length; end++)
430                         {
431                             if (error[end] == ';')
432                             {
433                                 pointer_string = error[start+4 .. end];
434                                 break;
435                             }
436                         }
437                         break;
438                     }
439                 }
440
441                 if (pointer_string != null)
442                 {
443                     void* p = cast (void*) string2int !(ulong) (pointer_string);
444                     LuaForwardException e = LuaForwardException.exceptions[p];
445                     LuaForwardException.exceptions.remove (p);
446                     e.forward ("LuaState.call");
447                     throw e;
448                 }
449                 else
450                 {
451                     throw new LuaCodeException (error);
452                 }
453             }
454         }
455         else
456         {
457             lua_call (this.state_, arguments, results);
458         }
459
460         return this;
461     }
462
463     /*******************************************************************************
464
465         Loads and runs the given string.
466
467         Params:
468         protection = whether this is a protected call. See LuaState.call
469         code = Lua code to run.
470         arguments = number of function arguments on the stack. Default is 0
471         results = expected number of return values. Default is a variable number.
472         chunk_name = Name of the code chunk.
473
474         Remarks:
475         Replaces luaL_dostring.
476
477     ******************************************************************************/
478
479     public LuaState doString (bool protection, char[] code, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES, char[] chunk_name = null)
480     {
481         load (code, chunk_name);
482
483         return call (protection, arguments, results);
484     }
485
486     /// ditto
487
488     public LuaState doString (bool protection, char[] code, char[] chunk_name, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES)
489     {
490         return doString (protection, code, arguments, results, chunk_name);
491     }
492
493     /*******************************************************************************
494
495         Loads and runs the given file.
496
497         Params:
498         protection = whether this is a protected call. See LuaState.call
499         filename = Lua file to run.
500         arguments = number of function arguments on the stack. Default is 0
501         results = expected number of return values. Default is a variable number.
502
503         Remarks:
504         Replaces luaL_dofile.
505
506     ******************************************************************************/
507
508     public LuaState doFile (bool protection, char[] filename, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES)
509     {
510         loadFile (filename);
511
512         return call (protection, arguments, results);
513     }
514
515     /*******************************************************************************
516
517         If the object at the specified index has a metatable with the specified
518         field, this method calls this field and passes the object as its only
519         argument. In this case this function returns true and pushes the returned
520         value onto the stack. If there is no metatable or no metamethod, this
521         function returns false without pushing any value on the stack.
522
523         Remarks:
524         Replaces luaL_callmeta.
525
526     ******************************************************************************/
527
528     public bool callMeta (int index, char[] field)
529     {
530         return luaL_callmeta (this.state_, index, toStringz (field)) != 0;
531     }
532
533     /*******************************************************************************
534
535         If the function argument is number, returns this number cast to an int.
536         If this argument is absent or is nil, returns the default value.
537         Otherwise, raises an error.
538
539         Remarks:
540         Replaces luaL_optint, luaL_optlong and luaL_optinteger.
541
542     ******************************************************************************/
543
544     public LuaInteger optInteger (uint argument, LuaInteger default_value)
545     {
546         return luaL_optint (this.state_, argument, default_value);
547     }
548
549     /*******************************************************************************
550
551         If the function argument is number, returns this number.
552         If this argument is absent or is nil, returns the default value.
553         Otherwise, raises an error.
554
555         Remarks:
556         Replaces luaL_optnumber.
557
558     ******************************************************************************/
559
560     public LuaNumber optNumber (uint argument, LuaNumber default_value)
561     {
562         return luaL_optnumber (this.state_, argument, default_value);
563     }
564
565     /*******************************************************************************
566
567         If the function argument is a string, returns this string. If this
568         argument is absent or is nil, returns the default value. Otherwise,
569         raises an error.
570
571         Remarks:
572         Replaces luaL_optlstring and luaL_optstring.
573
574     ******************************************************************************/
575
576     public char[] optString (uint argument, char[] default_value)
577     {
578         size_t len;
579         char* ptr = luaL_optlstring (this.state_, argument, toStringz (default_value), &len);
580
581         return ptr[0 .. len];
582     }
583
584     /*******************************************************************************
585
586         Checks whether the function argument is a string and searches for this
587         string in the array value_list. Returns the index in the array where the
588         string was found. Raises an error if the argument is not a string or if
589         the string cannot be found.
590
591         If default_value is not null, the function uses default_value as a default
592         value when there is no argument or if this argument is nil.
593
594         This is a useful function for mapping strings to enums. (The usual
595         convention in Lua libraries is to use strings instead of numbers to
596         select options.)
597
598         Remarks:
599         Replaces luaL_checkoption.
600
601     ******************************************************************************/
602
603     public int checkOption (uint argument, char[][] value_list, char[] default_value = null)
604     {
605         char[] name = (default_value !is null) ? optString (argument, default_value) : checkString (argument);
606
607         foreach (i, s; value_list)
608         {
609             if (s == name)
610                 return i;
611         }
612
613         throw new LuaCodeException ("Invalid option: '" ~ name ~ "'");
614     }
615
616     /*******************************************************************************
617
618         Raises a Lua error specified by the message argument. If the latter is
619         null, this method takes the object on top of the stack as the error
620         message. This method does a long jump, and therefore never returns.
621
622         Params:
623         message = The message to pass as the error code.
624
625         Remarks:
626         Replaces lua_error and luaL_error.
627
628     ******************************************************************************/
629
630     public int raiseError (char[] message = null)
631     {
632         if (message !is null)
633         {
634             pushString (message);
635         }
636         return lua_error (this.state_);
637     }
638
639     /*******************************************************************************
640
641         Raises a Lua error due to a bad function argument, where the function
642         name is taken from the call stack.
643
644         bad argument #<argument> to <function> (<message>)
645
646         This method does a long jump, and therefore never returns.
647
648         Params:
649         argument = Which argument is wrong or missing.
650         message = The error message.
651
652         Remarks:
653         Replaces luaL_argerror.
654
655     ******************************************************************************/
656
657     public int argumentError (uint argument, char[] message)
658     {
659         return luaL_argerror (this.state_, argument, toStringz (message));
660     }
661
662     /*******************************************************************************
663
664         Raises an error with a message like the following:
665
666         <loc>: bad argument <argument> to '<func>' (<typename> expected, got <rt>)
667
668         where loc is produced by LuaState.where, func is the name of the current
669         function, and rt is the type name of the actual argument.
670
671         This method does a long jump, and therefore never returns.
672
673         Params:
674         argument = Which argument is wrong or missing.
675         typename = The expected type name.
676
677         Remarks:
678         Replaces luaL_typerror.
679
680     ******************************************************************************/
681
682     public int typeError (uint argument, char[] typename)
683     {
684         return luaL_typerror (this.state_, argument, toStringz (typename));
685     }
686
687     /*******************************************************************************
688
689         Constructs a LuaBuffer and attaches it to this state.
690
691         Returns:
692         The constructed Lua buffer.
693
694     *******************************************************************************/
695
696     public LuaBuffer createBuffer ()
697     {
698         return new LuaBuffer (this);
699     }
700
701     /*******************************************************************************
702
703         Dumps a function as a binary chunk. Receives a Lua function on the top
704         of the stack and produces a binary chunk that, if loaded again, results
705         in a function equivalent to the one dumped. As it produces parts of the
706         chunk, dump call the delegate with the given data to write them.
707
708         The value returned is the error code returned by the last call to the
709         delegate; 0 means no errors.
710
711         This method does not pop the Lua function from the stack.
712
713         Params:
714         dg = Writer delegate
715
716         Remarks:
717         Replaces lua_dump.
718
719     *******************************************************************************/
720
721     public int dump (int delegate (char[] data) dg)
722     {
723         return lua_dump (this.state_, &writer, &dg);
724     }
725
726     /*******************************************************************************
727
728         Dumps a function as a binary chunk. It works exactly like the above dump
729         method, but instead of passing the data to a delegate, it returns the
730         complete result in one character array.
731
732     *******************************************************************************/
733
734     public char[] dump ()
735     {
736         char[] result = [];
737
738         int dumper (char[] data)
739         {
740             result ~= data;
741             return 0;
742         }
743
744         dump (&dumper);
745
746         return result;
747     }
748
749     /*******************************************************************************
750
751         Loads a Lua chunk. If there are no errors, load pushes the compiled
752         chunk as a Lua function on top of the stack. Otherwise, it raises
753         either a LuaCodeException, if the code cannot be compiled or a
754         LuaFatalException on other errors.
755
756         This function only loads a chunk; it does not run it. It automatically
757         detects whether the chunk is text or binary, and loads it accordingly.
758
759         The load method uses a user-supplied reader delegate to read the chunk,
760         which must return either data or null when called. The latter means,
761         that there is no further data to read.
762
763         The chunk_name argument gives a name to the chunk, which is used for
764         error messages and in debug information.
765         
766         ---
767         auto L = new LuaState;
768         L.doString (true, `
769         function fac (n)
770           if n == 0 then
771             return 1;
772           else
773             return n * fac(n-1);
774           end
775         end
776         `);
777
778         L.getGlobal ("fac"); // put function onto stack
779         char[] data = L.dump (); // dump it
780         L.pop (); // pop it
781         L.load (data, "foo"); // reload function as chunk 'foo'
782         L.setGlobal ("fac2"); // save it as the global function fac2
783         ---
784
785         Params:
786         dg = Reader delegate
787         chunk_name = Name of this chunk
788