2 +++ b/extensions/LUA/byte_array.c
5 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
6 + * by Andre Graf <andre@dergraf.org>
8 + * This program is free software; you can redistribute it and/or modify
9 + * it under the terms of the GNU General Public License as published by
10 + * the Free Software Foundation; either version 2 of the License, or
11 + * (at your option) any later version.
13 + * This program is distributed in the hope that it will be useful,
14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 + * GNU General Public License for more details.
18 + * You should have received a copy of the GNU General Public License
19 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 +#include "controller.h"
23 +/* Initialization helper function. This function should be used whenever
24 + * a new byte array need to be initialized. Depending on the arguments it
25 + * initializes the array in a different way. Have a look at the inline
27 +lua_packet_segment * init_byte_array(lua_State *L, unsigned char * start, int length, int do_copy)
29 + lua_packet_segment *array;
32 + luaL_error(L, "init_byte_array, requested size < 0");
34 + if (start && do_copy) {
35 + /* we have a start address where we copy from */
36 + array = lua_newuserdata(L, sizeof(lua_packet_segment) + length);
37 + array->start = (unsigned char *)array + sizeof(lua_packet_segment); /* aligning pointer */
38 + memcpy(array->start, start, length);
39 + }else if (start && !do_copy) {
40 + /* just link the start pointer, in this case you have to free the memory yourself */
41 + array = lua_newuserdata(L, sizeof(lua_packet_segment));
42 + array->start = start;
44 + /* create an empty array, fully managed by Lua */
45 + array = lua_newuserdata(L, sizeof(lua_packet_segment) + length);
46 + array->start = (unsigned char *)array + sizeof(lua_packet_segment); /* aligning pointer */
47 + memset(array->start, 0, length);
50 + array->length = length;
52 + array->changes = NULL;
54 + luaL_getmetatable(L, LUA_BYTE_ARRAY);
55 + lua_setmetatable(L, -2);
62 +/* LUA_API: get one byte of the given byte array
63 + * access-pattern: array[<index>] */
64 +static int32_t get_byte_array(lua_State *L)
66 + lua_packet_segment * array = checkbytearray(L, 1);
67 + int32_t index = luaL_checkinteger(L, 2); /* array starts with index 0 (not 1 as usual in Lua) */
69 + luaL_argcheck(L, 0 <= index && index < array->length, 1, "index out of range");
70 + lua_pushinteger(L, (array->start + array->offset)[index]);
75 +/* LUA_API: set one byte of the given byte array
76 + * access-pattern: array[<index>]= 0xFF */
77 +static int32_t set_byte_array(lua_State *L)
79 + lua_packet_segment * array = checkbytearray(L, 1);
81 + int32_t index = luaL_checkinteger(L, 2); /* array starts with index 0 (not 1 as usual in Lua) */
82 + int32_t val = luaL_checkinteger(L, 3);
83 + uint32_t nob = 1 << CHAR_BIT; /* we should use something like 1 << CHAR_BIT */
85 + luaL_argcheck(L, 0 <= index && index < array->length, 1, "index out of range");
86 + luaL_argcheck(L, 0 <= val && val < nob, 2, "cannot cast value to char");
88 + byte = (uint8_t)val;
90 + (array->start + array->offset)[index] = byte;
95 +/* LUA_API: get size of the given byte array
96 + * access-pattern: #array (__length meta-method) */
97 +static int32_t get_byte_array_size(lua_State *L)
99 + lua_packet_segment * array = checkbytearray(L, 1);
101 + lua_pushnumber(L, array->length);
107 +/* LUA_API: converts a given byte array to a string.
108 + * access-pattern: implicit through functions calling the
109 + * __to_string() metamethod , e.g. print32_t */
110 +static int32_t byte_array_to_string(lua_State *L)
112 + lua_packet_segment * array = checkbytearray(L, 1);
113 + uint8_t buf[(array->length * 3) + 255];
114 + uint8_t hexval[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
115 + char res[255 + (array->length * 3)]; /* make sure the buffer is big enough*/
117 + uint8_t *ptr = array->start + array->offset;
119 + for (i = 0; i < array->length; i++) {
120 + buf[i * 3] = hexval[(ptr[i] >> 4) & 0xF];
121 + buf[(i * 3) + 1] = hexval[ptr[i] & 0x0F];
122 + buf[(i * 3) + 2] = ' '; /* seperator */
125 + buf[array->length * 3] = '\0';
126 + n = sprintf(res, "byte_array: length: %d value: %s", array->length, buf);
128 + lua_pushlstring(L, res, n);
133 +static const struct luaL_Reg bytearray_lib_m [] = {
134 + { "__len", get_byte_array_size },
135 + { "__newindex", set_byte_array },
136 + { "__index", get_byte_array },
137 + { "__tostring", byte_array_to_string },
141 +void luaopen_bytearraylib(lua_State *L)
143 + luaL_newmetatable(L, LUA_BYTE_ARRAY);
144 + luaL_register(L, NULL, bytearray_lib_m);
150 +++ b/extensions/LUA/controller.c
153 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
154 + * by Andre Graf <andre@dergraf.org>
156 + * This program is free software; you can redistribute it and/or modify
157 + * it under the terms of the GNU General Public License as published by
158 + * the Free Software Foundation; either version 2 of the License, or
159 + * (at your option) any later version.
161 + * This program is distributed in the hope that it will be useful,
162 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
163 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
164 + * GNU General Public License for more details.
166 + * You should have received a copy of the GNU General Public License
167 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
170 +#if defined(__KERNEL__)
171 + #include <linux/mm.h>
173 +#include "controller.h"
175 +/* the array 'supported_protocols' holds all pointers to the
176 + * static and dynamic protocol buffers. It is filled by the
177 + * call to register_protbuf */
178 +static struct protocol_buf * supported_protocols[MAX_NR_OF_PROTOCOLS];
180 +/* C_API: the function 'get_protocol_buf' returns the pointer
181 + * to the protocol buffer of a given protocol id. */
182 +struct protocol_buf * get_protocol_buf(uint32_t protocol_id)
184 + return (struct protocol_buf *)supported_protocols[protocol_id];
188 +/* LUA_INT: the function 'gc_packet_segment' is triggered by the
189 + * garbage collector whenever a userdata annotated with one of
190 + * the protocol buffer metatable should be collected. */
191 +static int32_t gc_packet_segment(lua_State *L)
193 + lua_packet_segment * seg = (lua_packet_segment *)lua_touserdata(L, 1);
194 + if (seg && seg->changes) {
195 + seg->changes->ref_count--;
196 + if (seg->changes->ref_count <= 0) {
197 + kfree(seg->changes->field_length_changes);
198 + kfree(seg->changes->field_offset_changes);
199 + kfree(seg->changes);
200 + seg->changes = NULL;
207 +/* LUA_API: the function 'set_raw' is used to set the bytes of a segment
208 + * in 'raw' mode. The function is per default available in each protocol
209 + * buffer until it gets overridden by a specific setter function inside
210 + * a protocol buffer.
213 + * 1. lua_packet_segment (implicit)
214 + * 2. int32_t byte_value
217 + * 1. struct protocol_buf*
218 + * 2. int32_t field index, not used in this function
222 +static int32_t set_raw(lua_State *L)
228 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
229 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
231 + int32_t val = luaL_checkinteger(L, 2);
233 + nob = 1 << CHAR_BIT;
235 + luaL_argcheck(L, 0 <= val && val < nob, 2, "cannot cast value to char");
237 + byte = (uint8_t)val;
238 + ptr = seg->start + seg->offset;
240 + for (i = 0; i < seg->length; i++)
246 +/* LUA_API: the function 'get_raw' is used to get the bytes of a segment
247 + * in 'raw' mode. The function is per default available in each protocol
248 + * buffer until it gets overridden by a specific getter function inside
249 + * a protocol buffer.
252 + * 1. lua_packet_segment (implicit)
253 + * 2. uint32_t offset
254 + * 3. uint32_t length
257 + * 1. struct protocol_buf*
258 + * 2. int32_t field index, not used in this function
261 + * the byte array representing the given array
263 +static int32_t get_raw(lua_State *L)
265 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
266 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
268 + init_byte_array(L, seg->start + seg->offset, seg->length, 1);
272 +/* LUA_API: The function 'get_segment' is used to get a new segment in 'raw' mode.
273 + * Typically this function is applied on another raw segment in order
274 + * to extract a part of the segment as new segment.
277 + * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
278 + * 2. uint32_t offset, this indicates where to start the new segment, see e.g below.
279 + * 3. uint32_t length, this indicates the size of the new segment
282 + * 1. struct protocol_buf*
283 + * 2. int32_t field index, not used in this function
286 + * 1. A lua_packet_segment annotated with the according metatable or False in
287 + * case the input data is not valid
291 + * +------------------------+---------------------------------------+
292 + * | function call | resulting lua_packet_segment |
293 + * +========================+===+===+===+===+===+===+===+===+===+===+
294 + * | seg = packet:raw(0,10) | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
295 + * +------------------------+---+---+---+---+---+---+---+---+---+---+
296 + * | 1st_half = seg:raw(0,5)| 0 | 1 | 2 | 3 | 4 | |
297 + * +------------------------+---+---+---+---+---+---+---+---+---+---+
298 + * | 2nd_half = seg:raw(5,5)| | 5 | 6 | 7 | 8 | 9 |
299 + * +------------------------+-------------------+---+---+---+---+---+
301 +static int32_t get_segment(lua_State *L)
303 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
304 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
305 + uint32_t offset = luaL_checkinteger(L, 2);
306 + uint32_t length = luaL_checkinteger(L, 3);
307 + lua_packet_segment * new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
309 + new->start = seg->start;
310 + new->offset = seg->offset + offset;
311 + new->changes = NULL;
312 + /* we allow a seg->length == 0 , this enables processing packets where the packetsize is not fixed (0 = not fixed)*/
313 + if (seg->length != 0 && length > seg->length) {
314 + lua_pushboolean(L, 0);
318 + new->length = length;
319 + luaL_getmetatable(L, prot_buf->name);
320 + lua_setmetatable(L, -2);
325 +/* LUA_API: the function 'get_segment_size' is used to get the size of a segment.
328 + * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
331 + * 1. struct protocol_buf*
332 + * 2. int32_t field index, not used in this function
335 + * 1. Size as lua_Number
337 +static int32_t get_segment_size(lua_State *L)
339 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
340 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
342 + lua_pushnumber(L, seg->length);
346 +/* LUA_API: the function 'get_segment_offset' is used to get the real offset
347 + * of a segment. This function returns the offset of the segment to the start
348 + * of the buffer. This means the following
349 + * seg1 = packet:raw(2,10)
350 + * seg2 = seg1:raw(3,5)
351 + * offset = seg2:get_offset()
353 + * will give an offset of 5, since the seg1 starts at offset 2, and seg2 starts
354 + * at offset (seg1:get_offset() + 3).
357 + * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
360 + * 1. struct protocol_buf*
361 + * 2. int32_t field index, not used in this function
364 + * 1. Offset as lua_Number
366 +static int32_t get_segment_offset(lua_State *L)
368 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
369 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
371 + lua_pushnumber(L, seg->offset);
375 +/* LUA_API: overwrites the __tostring function of a lua_packet_segment.
376 + * this will print32_t a nicely formated string, including length,
377 + * offset and name of the protocol buffer.
380 + * 1. lua_packet_segment (implicit)
383 + * 1. the representing string
385 +static int32_t packet_segment_tostring(lua_State *L)
387 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
388 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
392 + n = sprintf(buf, "type: %s, offset: %d, length: %d", prot_buf->name, seg->offset, seg->length);
393 + lua_pushlstring(L, buf, n);
399 +static const struct luaL_Reg seg_access_functions [] = {
400 + { "set", set_raw },
401 + { "get", get_raw },
402 + { "raw", get_segment },
403 + { "get_offset", get_segment_offset },
404 + { "get_size", get_segment_size },
405 + { "to_bytes", get_raw },
406 + { "__tostring", packet_segment_tostring },
407 + { "__gc", gc_packet_segment },
411 +/* C_API: the function 'get_metatable_from_protocol_type' is a helper
412 + * used in controller.c as well as it may find usage in the static
413 + * protocol buffers and byte array implementation. */
414 +void get_metatable_from_protocol_type(lua_State *L, int32_t type)
417 + lua_getglobal(L, SUPPORTED_PROTOCOL_TABLE);
418 + lua_rawgeti(L, -1, type);
419 + table = (char *)luaL_checkstring(L, -1);
420 + lua_pop(L, 2); /* pop the table SUPPORTED_PROTOCOL_TABLE and the string pushed by lua_gettable */
421 + luaL_getmetatable(L, table);
425 +/* C_INT: the function 'payload_contains_protocol' is used internally.
426 + * Depending if static or dynamic protocol buffer it calls the right
427 + * validation function. */
428 +static int32_t payload_contains_protocol(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment *seg, uint32_t prot_type)
430 + if (prot_buf->is_dynamic)
431 + return has_protocol_dynamic(L, prot_buf, seg, prot_type);
433 + return prot_buf->has_protocol(L, prot_buf, seg, prot_type);
436 +/* C_INT: the function 'protocol_get_field_changes' is used interally.
437 + * It requests the field_changes struct calling the protocol buffers
438 + * 'get_field_changes' function. This funciton is called, whenever
439 + * the payload field with a given protocol type is requested inside
440 + * the function 'get_protocol_field' */
441 +static struct field_changes * protocol_get_field_changes(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg)
443 + struct field_changes * changes = NULL;
445 + if (prot_buf->get_field_changes) {
446 + if (prot_buf->is_dynamic)
447 + changes = get_field_changes_dynamic(L, prot_buf, seg);
449 + changes = prot_buf->get_field_changes(L, seg);
450 + /* is already 1 when set by helper 'get_allocated_field_changes,
451 + * since not every prot_buf may use this function we enforce it. */
452 + changes->ref_count = 1;
457 +/* C_INT: the function 'get_field_offset_in_bytes' wrapps the logic of
458 + * calculating the new length with considering the optional field_changes. */
459 +static int32_t get_field_offset_in_bytes(struct protocol_field * field, lua_packet_segment * seg, int32_t field_index)
461 + uint32_t nr_of_bits, nr_of_bytes, field_offset;
463 + field_offset = field->offset;
464 + /* do we need to manipulate the default values stored inside the protocol buffer ?? */
466 + field_offset += seg->changes->field_offset_changes[field_index];
467 + /* how many bits remain */
468 + nr_of_bits = field_offset & (CHAR_BIT - 1);
469 + /* assuming CHAR_BIT == 2 ^ 3 */
470 + nr_of_bytes = (field_offset - nr_of_bits) >> 3;
472 + return seg->offset + nr_of_bytes;
475 +/* C_INT: the function 'get_field_length_in_bytes' wrapps the logic of
476 + * calculating the new offset with considering the optional field_changes. */
477 +static int32_t get_field_length_in_bytes(struct protocol_field * field, lua_packet_segment * seg, int32_t field_index)
479 + uint32_t nr_of_bits, nr_of_bytes, field_length;
481 + field_length = field->length;
482 + /* if the field length is smaller than 1 byte, we take the size of one byte
483 + * we treat the case where field_length == 0 in a special way ...*/
484 + if (field_length < CHAR_BIT && field_length > 0)
485 + field_length = CHAR_BIT;
487 + /* do we need to manipulate the default values stored inside the protocol buffer ?? */
489 + field_length += seg->changes->field_length_changes[field_index];
490 + /* how many bits remain */
491 + nr_of_bits = field_length & (CHAR_BIT - 1);
492 + /* assuming CHAR_BIT == 2 ^ 3 */
493 + nr_of_bytes = (field_length - nr_of_bits) >> 3;
494 + return nr_of_bytes;
497 +/* C_INT: the function 'initialize_field_getter_and_setter' initializes
498 + * the setter and getter function of the field, considering the optional
499 + * field manipulator functions defined inside the protocol buffers. */
500 +static void initialize_field_getter_and_setter(lua_State *L, struct protocol_buf *prot_buf, int32_t field_index)
502 + /* lets check if there is a metatable on top of the stack */
503 + struct protocol_field * f = (struct protocol_field *)&prot_buf->protocol_fields[field_index];
505 + if (!lua_istable(L, -1)) luaL_error(L, "cannot initialize getter and setter for field %s->%s, "
506 + "not a table on top of the stack, is '%s'", prot_buf->name, f->name, lua_typename(L, lua_type(L, -1)));
508 + /* is there a 'getter' to initialize ? */
509 + lua_pushlightuserdata(L, prot_buf); /* push upvalue 1 */
510 + lua_pushinteger(L, field_index); /* push upvalue 2 */
512 + if (prot_buf->is_dynamic)
513 + lua_pushcclosure(L, field_dynamic_getter, 2);
515 + lua_pushcclosure(L, f->get, 2);
517 + /* there is no specific getter defined - fall back to 'get_raw' */
518 + lua_pushcclosure(L, get_raw, 2);
519 + /* set the metatable field 'get' */
520 + lua_setfield(L, -2, "get");
522 + /* is there a 'setter' to initialize ? */
523 + lua_pushlightuserdata(L, prot_buf); /* push upvalue 1 */
524 + lua_pushinteger(L, field_index); /* push upvalue 2 */
526 + if (prot_buf->is_dynamic)
527 + lua_pushcclosure(L, field_dynamic_setter, 2);
529 + lua_pushcclosure(L, f->set, 2);
531 + /* there is no specific setter defined - fall back to 'set_raw' */
532 + lua_pushcclosure(L, set_raw, 2);
533 + /* set the metatable field 'set' */
534 + lua_setfield(L, -2, "set");
537 +/* LUA_API: 'get_protocol_field' is used in Lua as a closure for each field of a protocol
538 + * buffer. E.g a call to ip = packet:data(packet_ip) will go to this function,
539 + * and trigger the conversion of the raw packet to a ip packet. Each call
540 + * to a field function of an IP packet, like ip:daddr() uses this function
541 + * to to return the right data. In each case you will end up either with a
542 + * new packet segment (annotated with the proper metatable) or a boolean
543 + * value (False) if something went wrong. In the case everything went fine,
544 + * the newly created lua_packet_segment is annotated with the proper
545 + * metatable where the fields get and set also contain the specific getter
546 + * and setter functions given by the protocol buffer. E.g. the function call
547 + * ip:daddr():get() or ip:daddr():set(...) will call the proper function
548 + * defined inside the corresponding field definition.
551 + * 1. lua_packet_segment, implicit through object oriented access seg:raw(..)
552 + * 2. type of the protocol buffer, optional, and only used if the accessed
553 + * field is the payload field. If a type is provided for the access of the
554 + * payload field, the function tries to convert the data pointed to by the
555 + * payload field to the given type. To check if such a conversion is
556 + * possible, it calls the function pointed to by the protocol buffer member
557 + * has_protocol. If this function returns True, the conversion takes place.
560 + * 1. struct protocol_buf*
561 + * 2. int32_t field index
564 + * 1. A lua_packet_segment annotated with the according metatable or False in
565 + * case the input data is not valid
567 +static int32_t get_protocol_field(lua_State *L)
570 + lua_packet_segment * seg, *new;
571 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
572 + int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
573 + struct protocol_field * field = &prot_buf->protocol_fields[field_index];
575 + /* get the current packet segment */
576 + seg = checkpacketseg(L, 1, prot_buf->name);
578 + /* initialize the new packet segment */
579 + new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
580 + new->start = seg->start; /* the start is unchanged */
581 + new->offset = get_field_offset_in_bytes(field, seg, field_index);
582 + new->length = get_field_length_in_bytes(field, seg, field_index);
584 + /* if new->length == 0 then no configuration was done, we guess the size by subtracting the
585 + * new offset from the packet length. since the old length is getting initialized by the
586 + * netfilter extension this assumption holds for the very last field of the protocol.
587 + * this 'feature' should be used by protocol buffers containing a payload, whereas the
588 + * payload field is the last field of the buffer. However, at compile-time unknown field
589 + * sizes (and offsets) of fields not being placed at the end of the protocol should be
590 + * initialized using the 'get_field_changes' hook system. */
591 + if (new->length == 0)
592 + new->length = (seg->length + seg->offset) - (new->offset);
594 + printf("%s->%s:: seg->offset %i, seg->length %i, new->offset %i, new->length %i\n",
595 + prot_buf->name, field->name, seg->offset, seg->length, new->offset, new->length);
597 + /* special care for packet payload requests */
598 + if (prot_buf->payload_field != NULL && strcmp(prot_buf->payload_field, field->name) == 0) {
599 + /* we know the payload field is requested */
600 + /* the requested payload can be delivered either as a common segment or as
601 + * an other packet type, such a conversion needs an extra protocol parameter
602 + * ... so lets check */
604 + if (lua_isnumber(L, 2)) {
605 + /* we have an extra parameter, ... lets see if it is a valid protocol
606 + * the parameter is the index of the 'supported_protocols'-array member */
607 + prot_type = lua_tointeger(L, 2);
608 + if (prot_type >= 0 && prot_type < PACKET_SENTINEL) {
609 + /* we are sure the purpose of the request is to get the payload data,
610 + * converted to the given protocol. lets check if the payload contains
611 + * data of the given protocol */
612 + if (payload_contains_protocol(L, prot_buf, seg, prot_type)) {
613 + /* success, we can push the metatable for the given protocol */
614 + get_metatable_from_protocol_type(L, prot_type);
615 + if (!lua_isnil(L, -1)) /* check if the metatable was found */
616 + /* perhaps the field offsets and lengths of the containing protocol
617 + * are not set correctly. request the optional 'field_changes' structure
618 + * holding the changes for lengths and offsets. */
619 + new->changes = protocol_get_field_changes(L, get_protocol_buf(prot_type), new);
621 + /* failed, the requested protocol is not available
622 + * we push false and return */
623 + lua_pop(L, 1); /* pop the userdata */
624 + lua_pushboolean(L, 0);
628 + /* payload does not carry the provided protocol */
629 + /* we push false and return */
630 + lua_pop(L, 1); /* pop the userdata */
631 + lua_pushboolean(L, 0);
635 + /* unknown protocol */
636 + lua_pop(L, 1); /* pop the userdata */
637 + luaL_error(L, "provided protocol is unknown");
642 + /* if there is still the 'new' userdata on the top, we push our own metatable */
643 + if (lua_isuserdata(L, -1)) {
644 + luaL_getmetatable(L, prot_buf->name);
645 + new->changes = seg->changes;
647 + new->changes->ref_count++;
650 + /* a new packet segment is at index -2 , and the proper metatable at index -1 of the stack
651 + * lets set the propper setter and getter function for the requested field */
652 + initialize_field_getter_and_setter(L, prot_buf, field_index);
654 + lua_setmetatable(L, -2);
658 +/* C_API: 'register_protbuf' is only used internally. This function takes a
659 + * pointer to a fully initialized protocol buffer struct and registers it
660 + * inside the Lua state. Registering means:
662 + * 1. it creates a new metatable with the name of the protocol buffer.
663 + * 2. it registers the default functions which are stored in the luaL_Reg
664 + * array seg_access_functions.
665 + * 3. it loops over the protocol fields stored at prot_buf->protocol_fields
666 + * and registers a new function (using the field name) inside the
667 + * metatable. Each field points to the function 'get_protocol_field'
668 + * which acts as a closure taking a pointer to the protocol buffer as
669 + * well as the index of the field as upvalues.
670 + * 4. The protocol index, serves as numerical identifier of this protocol
671 + * buffer or even of the protocol itself. This index is stored as a
672 + * global value inside the Lua state as well as inside the Lua table
673 + * 'supported_protocols'. Assuming the name of a procotol buffer is
674 + * "packet_ip" the following statements are true:
676 + * supported_protocols[protocol_index] == "packet_ip"
677 + * packet_ip == protocol_index
679 + * This allows you to get all registered protocols from within Lua. This
680 + * is especially usefull for the dynamic protocol buffers where you have
681 + * to provide your own "has_protocol"-function, which probably needs the
682 + * information on which protocols it is able to contain.
684 +void register_protbuf(lua_State *L, struct protocol_buf * prot_buf, uint32_t protocol_index)
686 + int32_t field_index;
687 + luaL_Reg *reg = (struct luaL_Reg *)seg_access_functions;
688 + struct protocol_field * field = prot_buf->protocol_fields;
690 + luaL_newmetatable(L, prot_buf->name);
692 + /* metatable.__index = metatable */
693 + lua_pushvalue(L, -1); /* duplicates the metatable */
694 + lua_setfield(L, -2, "__index");
696 + /* pushing default functions */
697 + for (; reg->name; reg++) {
698 + lua_pushlightuserdata(L, (void *)prot_buf);
699 + lua_pushcclosure(L, reg->func, 1);
700 + lua_setfield(L, -2, reg->name);
703 + /* pushing functions specific to the protocol buffer */
704 + for (field_index = 0; field->name; field++, field_index++) {
705 + lua_pushlightuserdata(L, (void *)prot_buf); /* upvalue: prot_buf */
706 + lua_pushinteger(L, field_index); /* upvalue: index of protocol field */
707 + lua_pushcclosure(L, get_protocol_field, 2);
708 + lua_setfield(L, -2, field->name);
710 + /* pop the metatable */
713 + /* registering the array-index as the protocol_id*/
714 + lua_getglobal(L, "_G");
715 + lua_pushinteger(L, protocol_index);
716 + lua_setfield(L, -2, prot_buf->name);
717 + lua_pop(L, 1); /* pop _G */
719 + lua_getglobal(L, SUPPORTED_PROTOCOL_TABLE);
720 + lua_pushstring(L, prot_buf->name);
721 + lua_rawseti(L, -2, protocol_index);
723 + lua_pop(L, 1); /* pop SUPPORTED_PROTOCOL_TABLE */
725 + supported_protocols[protocol_index] = prot_buf;
728 +void luaopen_controller(lua_State *L)
730 + /* registering a table inside the _G with table[protocol_index] = prot_buf->name */
731 + lua_getglobal(L, "_G");
733 + lua_setfield(L, -2, SUPPORTED_PROTOCOL_TABLE);
734 + lua_pop(L, 1); /* pop _G */
736 + luaopen_protbuf_raw(L);
737 + luaopen_protbuf_eth(L);
738 + luaopen_protbuf_ip(L);
739 + luaopen_protbuf_icmp(L);
740 + luaopen_protbuf_tcp(L);
741 + luaopen_protbuf_tcp_options(L);
742 + luaopen_protbuf_udp(L);
743 + luaopen_protbuf_tftp(L);
744 + luaopen_protbuf_dynamic(L);
745 + /* should follow all other static buffers */
746 +#if defined(__KERNEL__)
750 + luaopen_bytearraylib(L);
757 +++ b/extensions/LUA/controller.h
760 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
761 + * by Andre Graf <andre@dergraf.org>
763 + * This program is free software; you can redistribute it and/or modify
764 + * it under the terms of the GNU General Public License as published by
765 + * the Free Software Foundation; either version 2 of the License, or
766 + * (at your option) any later version.
768 + * This program is distributed in the hope that it will be useful,
769 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
770 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
771 + * GNU General Public License for more details.
773 + * You should have received a copy of the GNU General Public License
774 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
777 +#ifndef CONTROLLER_H_
778 +#define CONTROLLER_H_
780 +#include "stdlib.h" /* wrapper */
781 +#include "string.h" /* wrapper */
784 +#include "lauxlib.h"
786 +#if defined(__KERNEL__)
787 +#include <linux/skbuff.h>
788 +#include <linux/slab.h>
789 +#include <linux/vmalloc.h>
793 +/* to compile the stuff in userspace (for testing)*/
794 +#if !defined(__KERNEL__)
796 +#define pr_debug printf;
798 +#define kmalloc(size, type) malloc(size)
799 +#define kfree(ptr) free(ptr)
804 +/**********************************************************************/
805 +/* nf Lua configuration */
806 +/**********************************************************************/
807 +#define MAX_NR_OF_PROTOCOLS 16
808 +#define SUPPORTED_PROTOCOL_TABLE "supported_protocols"
810 +#define MAX_NR_OF_FIELDS_IN_DYN_PROT_BUF 32
813 +/**********************************************************************/
814 +/* Static Protocol Buffer configuration */
815 +/**********************************************************************/
817 +/* the definitions of the stringified expression of the prot_bufs...
818 + * make sure all static prot_bufs are listed and are unique */
819 +#define LUA_PACKET_SEG_RAW "packet_raw"
820 +#define LUA_PACKET_SEG_ETH "packet_eth"
821 +#define LUA_PACKET_SEG_ICMP "packet_icmp"
822 +#define LUA_PACKET_SEG_IP "packet_ip"
823 +#define LUA_PACKET_SEG_TCP "packet_tcp"
824 +#define LUA_PACKET_SEG_TCP_OPT "packet_tcp_opt"
825 +#define LUA_PACKET_SEG_UDP "packet_udp"
826 +#define LUA_PACKET_SEG_TFTP "packet_tftp"
828 +/* the enum holding all static prot_bufs... make sure it contains all
829 + * static prot_bufs */
836 + PACKET_TCP_OPTIONS,
843 +/* the luaopen-function of the prot_bufs... make sure it is called
844 + * inside luaopen_controller */
845 +void luaopen_protbuf_raw(lua_State *L);
846 +void luaopen_protbuf_eth(lua_State *L);
847 +void luaopen_protbuf_ip(lua_State *L);
848 +void luaopen_protbuf_icmp(lua_State *L);
849 +void luaopen_protbuf_tcp(lua_State *L);
850 +void luaopen_protbuf_tcp_options(lua_State *L);
851 +void luaopen_protbuf_udp(lua_State *L);
852 +void luaopen_protbuf_tftp(lua_State *L);
853 +void luaopen_protbuf_dynamic(lua_State *L);
855 +/**********************************************************************/
857 +/**********************************************************************/
858 +struct field_changes {
860 + int *field_length_changes;
861 + int *field_offset_changes;
864 +/**********************************************************************/
865 +/* lua packet segment */
866 +/* ------------------ */
867 +/* The struct lua_packet_segment is the integral part of a Lua packet.*/
868 +/* At the very beginning, when a new packet arrives in `lua_tg`_ such */
869 +/* a struct is initialized. The field start then points to the lowest */
870 +/* available header inside the sk_buff structure. During packet */
871 +/* processing the start pointer remains the same, only the offset and */
872 +/* length value change. */
873 +/**********************************************************************/
874 +#define checkpacketseg(L, i, seg_type) \
875 + (lua_packet_segment *)luaL_checkudata(L, i, seg_type)
877 +typedef struct lua_packet_segment {
878 + unsigned int offset;
879 + unsigned int length;
880 + struct field_changes * changes;
881 + unsigned char * start; /* need to be at the end because of the memory alignment */
882 +} lua_packet_segment;
884 +/**********************************************************************/
885 +/* protocol field */
886 +/* -------------- */
887 +/* This structure is a container for the field definitions used by the*/
888 +/* protocol buffer. Each protocol field is expressed using this struct*/
889 +/* Have a look at the protocol buffers to see how the struct gets */
893 +/* This member expresses the name of the field, ending */
894 +/* in its own Lua function to access the field. */
895 +/* offset / length: */
896 +/* These members do specify the position inside the protocol header */
897 +/* in bits (not bytes!). */
899 +/* The get and set functions take a function pointer pointing to the*/
900 +/* specific getter and setter function for this field. */
901 +/**********************************************************************/
902 +struct protocol_field {
909 +#define PROT_FIELD_SENTINEL { NULL, 0, 0, NULL, NULL }
912 +/**********************************************************************/
914 +/**********************************************************************/
915 +/* This structure is a container for all the information needed for a
916 + * protocol buffer. It gets initialized in each protocol buffer header
917 + * file or for the dynamic protocol buffers on runtime using the
918 + * 'register_dynamic_protocol_buffer' function.
921 + * This member is used throughout the system. It is also exported
922 + * to Lua as a variable name holding the index of the 'supported_protocols'
923 + * array. The name is also used as the name of the generated Lua
924 + * metatable, that is why inside the macro checkpacketseg_ it
925 + * is always the name of a protocol buffer that is passed as the
926 + * second parameter.
928 + * This member holds the string of the field responsible for payload
929 + * data. The payload field of a protocol has an extra property, since
930 + * it can be used to invoke another protocol buffer that is applied to
931 + * the payload content.
933 + * This member is used together with the payload_field. Since we must
934 + * be sure that the payload content does really contain a protocol
935 + * of type X. The function pointed to by has_protocol checks if the
936 + * protocol buffer X can be applied on the payload_data.
938 + * This member points to the array of 'protocol_field' structures
939 + * get_field_changes:
940 + * This member is optional. It is used to return a pointer to an initialized
941 + * field_changes struct. The function is called, whenever the payload field
942 + * is requested with a given protocol type. Usually this function will
943 + * initialize the field_changes struct depending on the content of the
944 + * payload data. e.g.
945 + * tcp = ip:data(packet_tcp)
946 + * such a request will call the 'get_field_changes' function of the tcp
947 + * protocol buffer. This enables, that the tcp options field have the proper
948 + * length as well as the tcp data start at the right offset.
950 +struct protocol_buf {
953 + char * payload_field;
954 + int (*has_protocol)(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg, int type);
955 + struct protocol_field * protocol_fields;
956 + struct field_changes * (*get_field_changes)(lua_State *L, lua_packet_segment * seg);
959 +/**********************************************************************/
960 +/* lua byte array library */
961 +/**********************************************************************/
962 +#define LUA_BYTE_ARRAY "byte_array"
963 +#define checkbytearray(L, i) \
964 + (lua_packet_segment *)luaL_checkudata(L, i, LUA_BYTE_ARRAY)
965 +lua_packet_segment * init_byte_array(lua_State *L, unsigned char * start, int length, int do_copy);
966 +void luaopen_bytearraylib(lua_State *L);
969 +/**********************************************************************/
970 +/* lua netfilter environment library */
971 +/**********************************************************************/
972 +#define NETFILTER_LIB "nf"
973 +#if defined(__KERNEL__)
976 + /* perhaps more to come here (e.g. a state per CPU) */
978 + #define LUA_ENV "lua_env"
979 + #define checkluaenv(L, i) \
980 + (struct lua_env *)luaL_checkudata(L, i, LUA_ENV)
982 + void luaopen_nflib(lua_State *L);
985 +void cleanup_dynamic_prot_bufs(void); /* freeing all dynamic prot bufs */
986 +/**********************************************************************/
987 +/* lua protbuf helpers */
988 +/**********************************************************************/
989 +int get_1_bit_generic(lua_State *L);
990 +int set_1_bit_generic(lua_State *L);
991 +int get_lower_4_bit_generic(lua_State *L);
992 +int set_lower_4_bit_generic(lua_State *L);
993 +int get_upper_4_bit_generic(lua_State *L);
994 +int set_upper_4_bit_generic(lua_State *L);
995 +int get_8_bit_generic(lua_State *L);
996 +int set_8_bit_generic(lua_State *L);
997 +int get_16_bit_generic(lua_State *L);
998 +int set_16_bit_generic(lua_State *L);
999 +int get_32_bit_generic(lua_State *L);
1000 +int set_32_bit_generic(lua_State *L);
1001 +int set_data_generic(lua_State *L);
1002 +int get_string_generic(lua_State *L);
1003 +int get_byte_generic_str(lua_State *L);
1004 +struct field_changes * get_allocated_field_changes(lua_State *L, int nr_of_fields);
1006 +/* only used by the dynamic prot buf subsystem */
1007 +#define MAX_NR_OF_DYN_PROT_BUFS 16
1008 +int field_dynamic_setter(lua_State *L);
1009 +int field_dynamic_getter(lua_State *L);
1010 +int has_protocol_dynamic(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int type);
1011 +struct field_changes * get_field_changes_dynamic(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg);
1013 +/**********************************************************************/
1014 +/* lua controller API */
1015 +/**********************************************************************/
1016 +void luaopen_controller(lua_State *L);
1017 +struct protocol_buf * get_protocol_buf(unsigned int protocol_id);
1018 +void get_metatable_from_protocol_type(lua_State *L, int type);
1019 +void register_protbuf(lua_State *L, struct protocol_buf * prot_buf, unsigned int protocol_index);
1022 +#endif /* CONTROLLER_H_ */
1024 +++ b/extensions/LUA/Kbuild
1028 +# Adding debug options
1029 +EXTRA_CFLAGS += -DDEBUG
1033 +EXTRA_CFLAGS += -I$(src)/prot_buf_new
1034 +xt_LUA-y += xt_LUA_target.o \
1036 +xt_LUA-y += nf_lua.o \
1037 + prot_buf_helpers.o \
1040 + prot_buf_ethernet.o \
1047 + prot_buf_dynamic.o \
1050 +# Adding Lua Support
1051 +EXTRA_CFLAGS += -I$(src)/lua -I$(src)/lua/include
1052 +xt_LUA-y += lua/lapi.o \
1076 +++ b/extensions/LUA/libxt_LUA.c
1079 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
1080 + * by Andre Graf <andre@dergraf.org>
1082 + * This program is free software; you can redistribute it and/or modify
1083 + * it under the terms of the GNU General Public License as published by
1084 + * the Free Software Foundation; either version 2 of the License, or
1085 + * (at your option) any later version.
1087 + * This program is distributed in the hope that it will be useful,
1088 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1089 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1090 + * GNU General Public License for more details.
1092 + * You should have received a copy of the GNU General Public License
1093 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
1096 +#include <getopt.h>
1098 +#include <stdbool.h>
1099 +#include <stdlib.h>
1100 +#include <string.h>
1101 +#include <xtables.h>
1102 +#include <linux/netfilter.h>
1103 +#include <linux/netfilter/x_tables.h>
1104 +#include "xt_LUA.h"
1107 + FLAG_SCRIPT = 1 << 0,
1108 + FLAG_STATE = 1 << 1,
1109 + FLAG_FUNCTION = 1 << 2,
1112 +static const struct option lua_tg_opts[] = {
1113 + { .name = "script", .has_arg = true, .val = 's' },
1114 + { .name = "state", .has_arg = true, .val = 'l' },
1115 + { .name = "function", .has_arg = true, .val = 'f' },
1120 +static void lua_tg_help(void)
1123 + "LUA target options:\n"
1124 + " --script SCRIPT Process packet with the Lua script given by SCRIPT\n"
1126 + " --state ID Process packet within the Lua state given by ID.\n"
1127 + " Omitting --state infers the ID 0, which can be\n"
1128 + " refered to the 'global' state.\n"
1130 + " --function FUNCTION Name of the function that processes the Lua packet\n"
1135 +lua_tg_init(struct xt_entry_target *target)
1137 + struct xt_lua_tginfo *info = (void *)target->data;
1139 + info->state_id = 0;
1140 + strncpy(info->function, "process_packet\0", sizeof("process_packet\0"));
1144 +lua_tg_parse(int32_t c, char **argv, int32_t invert, uint32_t *flags,
1145 + const void *entry, struct xt_entry_target **target)
1147 + struct xt_lua_tginfo *info = (void *)(*target)->data;
1148 + char buf[MAX_SCRIPT_SIZE];
1150 + uint32_t state_id;
1155 + if (*flags & FLAG_SCRIPT)
1156 + xtables_error(PARAMETER_PROBLEM,
1157 + "LUA: Cannot specify --script more than once");
1159 + if (strlen(optarg) > sizeof(info->filename))
1160 + xtables_error(PARAMETER_PROBLEM,
1161 + "LUA: Maximum script length is %zu",
1162 + sizeof(info->filename));
1164 + if (strchr(optarg, '\n'))
1165 + xtables_error(PARAMETER_PROBLEM,
1166 + "LUA: Newlines not allowed in script name");
1167 + file = fopen(optarg, "rb");
1168 + if (file != NULL) {
1169 + fseek(file, 0, SEEK_END);
1170 + script_size = ftell(file);
1171 + if (script_size > MAX_SCRIPT_SIZE)
1172 + xtables_error(PARAMETER_PROBLEM,
1173 + "LUA: The size of the script is too big");
1175 + fseek(file, 0, SEEK_SET);
1176 + fread(buf, script_size, 1, file);
1179 + xtables_error(PARAMETER_PROBLEM,
1180 + "LUA: Cannot open script %s", optarg);
1182 + strncpy(info->filename, optarg, sizeof(info->filename));
1183 + strncpy(info->buf, buf, sizeof(info->buf));
1184 + info->script_size = script_size;
1186 + *flags |= FLAG_SCRIPT;
1190 + if (*flags & FLAG_STATE)
1191 + xtables_error(PARAMETER_PROBLEM,
1192 + "LUA: Cannot specify --state more than once");
1194 + if (!xtables_strtoui(optarg, NULL, &state_id, 0, 8))
1195 + xtables_error(PARAMETER_PROBLEM,
1196 + "LUA: Invalid --state %s", optarg);
1198 + info->state_id = state_id;
1199 + *flags |= FLAG_STATE;
1203 + if (*flags & FLAG_FUNCTION)
1204 + xtables_error(PARAMETER_PROBLEM,
1205 + "LUA: Cannot specify --function more than once");
1206 + if (strlen(optarg) > sizeof(info->function))
1207 + xtables_error(PARAMETER_PROBLEM,
1208 + "LUA: Maximum function length is %zu",
1209 + sizeof(info->function));
1211 + if (strchr(optarg, '\n'))
1212 + xtables_error(PARAMETER_PROBLEM,
1213 + "LUA: Newlines not allowed in function name");
1215 + strncpy(info->function, optarg, sizeof(info->function));
1217 + *flags |= FLAG_FUNCTION;
1225 +lua_tg_check(uint32_t flags)
1228 + xtables_error(PARAMETER_PROBLEM, "LUA: --script parameter required");
1232 +lua_tg_print(const void *entry, const struct xt_entry_target *target,
1235 + const struct xt_lua_tginfo *info = (const void *)target->data;
1237 + printf("LUA script: %s ", info->filename);
1241 +lua_tg_save(const void *entry, const struct xt_entry_target *target)
1243 + const struct xt_lua_tginfo *info = (const void *)target->data;
1245 + printf("--script %s ", info->filename);
1248 +static struct xtables_target lua_tg_reg = {
1250 + .version = XTABLES_VERSION,
1252 + .family = NFPROTO_UNSPEC,
1253 + .size = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
1254 + .userspacesize = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
1255 + .help = lua_tg_help,
1256 + .init = lua_tg_init,
1257 + .parse = lua_tg_parse,
1258 + .final_check = lua_tg_check,
1259 + .print = lua_tg_print,
1260 + .save = lua_tg_save,
1261 + .extra_opts = lua_tg_opts,
1264 +static __attribute__((constructor)) void lua_tg_ldr(void)
1266 + xtables_register_target(&lua_tg_reg);
1270 +++ b/extensions/LUA/libxt_LUA.man
1272 +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
1274 +++ b/extensions/LUA/lua/include/ctype.h
1276 +#include <linux/ctype.h>
1278 +#define isalnum(c) (((__ismask(c)&(_U|_L|_D)) != 0) && (c > 0))
1280 +#define isalpha(c) (((__ismask(c)&(_U|_L)) != 0) && (c > 0))
1282 +#define iscntrl(c) (((__ismask(c)&(_C)) != 0) && (c > 0))
1284 +#define isdigit(c) (((__ismask(c)&(_D)) != 0) && (c > 0))
1286 +#define isspace(c) (((__ismask(c)&(_S)) != 0) && (c > 0))
1288 +++ b/extensions/LUA/lua/include/errno.h
1290 +#include <linux/errno.h>
1292 +++ b/extensions/LUA/lua/include/locale.h
1295 + char * decimal_point ;
1298 +#define localeconv() NULL
1300 +++ b/extensions/LUA/lua/include/setjmp.h
1303 + * arch/um/include/sysdep-i386/archsetjmp.h
1306 +#ifndef _KLIBC_ARCHSETJMP_H
1307 +#define _KLIBC_ARCHSETJMP_H
1310 + unsigned int __ebx;
1311 + unsigned int __esp;
1312 + unsigned int __ebp;
1313 + unsigned int __esi;
1314 + unsigned int __edi;
1315 + unsigned int __eip;
1318 +typedef struct __jmp_buf jmp_buf[1];
1320 +#define JB_IP __eip
1321 +#define JB_SP __esp
1323 +int setjmp(jmp_buf);
1324 +void longjmp(jmp_buf, int);
1326 +#endif /* _SETJMP_H */
1329 +++ b/extensions/LUA/lua/include/stdio.h
1331 +#include <linux/kernel.h>
1333 +++ b/extensions/LUA/lua/include/stdlib.h
1335 +#include <linux/kernel.h>
1337 +#define exit(E) return
1338 +#define strtoul simple_strtoul
1339 +#define strcoll strcmp
1343 +++ b/extensions/LUA/lua/include/string.h
1345 +#include <linux/string.h>
1347 +++ b/extensions/LUA/lua/lapi.c
1350 +** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
1352 +** See Copyright Notice in lua.h
1355 +#include <stdarg.h>
1357 +#include <assert.h>
1358 +#include <string.h>
1366 +#include "ldebug.h"
1371 +#include "lobject.h"
1372 +#include "lstate.h"
1373 +#include "lstring.h"
1374 +#include "ltable.h"
1376 +#include "lundump.h"
1381 +const char lua_ident[] =
1382 + "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
1383 + "$Authors: " LUA_AUTHORS " $\n"
1384 + "$URL: www.lua.org $\n";
1388 +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
1390 +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
1392 +#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
1396 +static TValue *index2adr (lua_State *L, int idx) {
1398 + TValue *o = L->base + (idx - 1);
1399 + api_check(L, idx <= L->ci->top - L->base);
1400 + if (o >= L->top) return cast(TValue *, luaO_nilobject);
1403 + else if (idx > LUA_REGISTRYINDEX) {
1404 + api_check(L, idx != 0 && -idx <= L->top - L->base);
1405 + return L->top + idx;
1407 + else switch (idx) { /* pseudo-indices */
1408 + case LUA_REGISTRYINDEX: return registry(L);
1409 + case LUA_ENVIRONINDEX: {
1410 + Closure *func = curr_func(L);
1411 + sethvalue(L, &L->env, func->c.env);
1414 + case LUA_GLOBALSINDEX: return gt(L);
1416 + Closure *func = curr_func(L);
1417 + idx = LUA_GLOBALSINDEX - idx;
1418 + return (idx <= func->c.nupvalues)
1419 + ? &func->c.upvalue[idx-1]
1420 + : cast(TValue *, luaO_nilobject);
1426 +static Table *getcurrenv (lua_State *L) {
1427 + if (L->ci == L->base_ci) /* no enclosing function? */
1428 + return hvalue(gt(L)); /* use global table as environment */
1430 + Closure *func = curr_func(L);
1431 + return func->c.env;
1436 +void luaA_pushobject (lua_State *L, const TValue *o) {
1437 + setobj2s(L, L->top, o);
1442 +LUA_API int lua_checkstack (lua_State *L, int size) {
1445 + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
1446 + res = 0; /* stack overflow */
1447 + else if (size > 0) {
1448 + luaD_checkstack(L, size);
1449 + if (L->ci->top < L->top + size)
1450 + L->ci->top = L->top + size;
1457 +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
1459 + if (from == to) return;
1461 + api_checknelems(from, n);
1462 + api_check(from, G(from) == G(to));
1463 + api_check(from, to->ci->top - to->top >= n);
1465 + for (i = 0; i < n; i++) {
1466 + setobj2s(to, to->top++, from->top + i);
1472 +LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
1473 + to->nCcalls = from->nCcalls;
1477 +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
1478 + lua_CFunction old;
1480 + old = G(L)->panic;
1481 + G(L)->panic = panicf;
1487 +LUA_API lua_State *lua_newthread (lua_State *L) {
1491 + L1 = luaE_newthread(L);
1492 + setthvalue(L, L->top, L1);
1495 + luai_userstatethread(L, L1);
1502 +** basic stack manipulation
1506 +LUA_API int lua_gettop (lua_State *L) {
1507 + return cast_int(L->top - L->base);
1511 +LUA_API void lua_settop (lua_State *L, int idx) {
1514 + api_check(L, idx <= L->stack_last - L->base);
1515 + while (L->top < L->base + idx)
1516 + setnilvalue(L->top++);
1517 + L->top = L->base + idx;
1520 + api_check(L, -(idx+1) <= (L->top - L->base));
1521 + L->top += idx+1; /* `subtract' index (index is negative) */
1527 +LUA_API void lua_remove (lua_State *L, int idx) {
1530 + p = index2adr(L, idx);
1531 + api_checkvalidindex(L, p);
1532 + while (++p < L->top) setobjs2s(L, p-1, p);
1538 +LUA_API void lua_insert (lua_State *L, int idx) {
1542 + p = index2adr(L, idx);
1543 + api_checkvalidindex(L, p);
1544 + for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
1545 + setobjs2s(L, p, L->top);
1550 +LUA_API void lua_replace (lua_State *L, int idx) {
1553 + /* explicit test for incompatible code */
1554 + if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
1555 + luaG_runerror(L, "no calling environment");
1556 + api_checknelems(L, 1);
1557 + o = index2adr(L, idx);
1558 + api_checkvalidindex(L, o);
1559 + if (idx == LUA_ENVIRONINDEX) {
1560 + Closure *func = curr_func(L);
1561 + api_check(L, ttistable(L->top - 1));
1562 + func->c.env = hvalue(L->top - 1);
1563 + luaC_barrier(L, func, L->top - 1);
1566 + setobj(L, o, L->top - 1);
1567 + if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
1568 + luaC_barrier(L, curr_func(L), L->top - 1);
1575 +LUA_API void lua_pushvalue (lua_State *L, int idx) {
1577 + setobj2s(L, L->top, index2adr(L, idx));
1585 +** access functions (stack -> C)
1589 +LUA_API int lua_type (lua_State *L, int idx) {
1590 + StkId o = index2adr(L, idx);
1591 + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
1595 +LUA_API const char *lua_typename (lua_State *L, int t) {
1597 + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
1601 +LUA_API int lua_iscfunction (lua_State *L, int idx) {
1602 + StkId o = index2adr(L, idx);
1603 + return iscfunction(o);
1607 +LUA_API int lua_isnumber (lua_State *L, int idx) {
1609 + const TValue *o = index2adr(L, idx);
1610 + return tonumber(o, &n);
1614 +LUA_API int lua_isstring (lua_State *L, int idx) {
1615 + int t = lua_type(L, idx);
1616 + return (t == LUA_TSTRING || t == LUA_TNUMBER);
1620 +LUA_API int lua_isuserdata (lua_State *L, int idx) {
1621 + const TValue *o = index2adr(L, idx);
1622 + return (ttisuserdata(o) || ttislightuserdata(o));
1626 +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
1627 + StkId o1 = index2adr(L, index1);
1628 + StkId o2 = index2adr(L, index2);
1629 + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
1630 + : luaO_rawequalObj(o1, o2);
1634 +LUA_API int lua_equal (lua_State *L, int index1, int index2) {
1637 + lua_lock(L); /* may call tag method */
1638 + o1 = index2adr(L, index1);
1639 + o2 = index2adr(L, index2);
1640 + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
1646 +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
1649 + lua_lock(L); /* may call tag method */
1650 + o1 = index2adr(L, index1);
1651 + o2 = index2adr(L, index2);
1652 + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
1653 + : luaV_lessthan(L, o1, o2);
1660 +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
1662 + const TValue *o = index2adr(L, idx);
1663 + if (tonumber(o, &n))
1670 +LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
1672 + const TValue *o = index2adr(L, idx);
1673 + if (tonumber(o, &n)) {
1675 + lua_Number num = nvalue(o);
1676 + lua_number2integer(res, num);
1684 +LUA_API int lua_toboolean (lua_State *L, int idx) {
1685 + const TValue *o = index2adr(L, idx);
1686 + return !l_isfalse(o);
1690 +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
1691 + StkId o = index2adr(L, idx);
1692 + if (!ttisstring(o)) {
1693 + lua_lock(L); /* `luaV_tostring' may create a new string */
1694 + if (!luaV_tostring(L, o)) { /* conversion failed? */
1695 + if (len != NULL) *len = 0;
1700 + o = index2adr(L, idx); /* previous call may reallocate the stack */
1703 + if (len != NULL) *len = tsvalue(o)->len;
1708 +LUA_API size_t lua_objlen (lua_State *L, int idx) {
1709 + StkId o = index2adr(L, idx);
1710 + switch (ttype(o)) {
1711 + case LUA_TSTRING: return tsvalue(o)->len;
1712 + case LUA_TUSERDATA: return uvalue(o)->len;
1713 + case LUA_TTABLE: return luaH_getn(hvalue(o));
1714 + case LUA_TNUMBER: {
1716 + lua_lock(L); /* `luaV_tostring' may create a new string */
1717 + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
1721 + default: return 0;
1726 +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
1727 + StkId o = index2adr(L, idx);
1728 + return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
1732 +LUA_API void *lua_touserdata (lua_State *L, int idx) {
1733 + StkId o = index2adr(L, idx);
1734 + switch (ttype(o)) {
1735 + case LUA_TUSERDATA: return (rawuvalue(o) + 1);
1736 + case LUA_TLIGHTUSERDATA: return pvalue(o);
1737 + default: return NULL;
1742 +LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
1743 + StkId o = index2adr(L, idx);
1744 + return (!ttisthread(o)) ? NULL : thvalue(o);
1748 +LUA_API const void *lua_topointer (lua_State *L, int idx) {
1749 + StkId o = index2adr(L, idx);
1750 + switch (ttype(o)) {
1751 + case LUA_TTABLE: return hvalue(o);
1752 + case LUA_TFUNCTION: return clvalue(o);
1753 + case LUA_TTHREAD: return thvalue(o);
1754 + case LUA_TUSERDATA:
1755 + case LUA_TLIGHTUSERDATA:
1756 + return lua_touserdata(L, idx);
1757 + default: return NULL;
1764 +** push functions (C -> stack)
1768 +LUA_API void lua_pushnil (lua_State *L) {
1770 + setnilvalue(L->top);
1776 +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
1778 + setnvalue(L->top, n);
1784 +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
1786 + setnvalue(L->top, cast_num(n));
1792 +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
1795 + setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
1801 +LUA_API void lua_pushstring (lua_State *L, const char *s) {
1805 + lua_pushlstring(L, s, strlen(s));
1809 +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
1814 + ret = luaO_pushvfstring(L, fmt, argp);
1820 +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
1825 + va_start(argp, fmt);
1826 + ret = luaO_pushvfstring(L, fmt, argp);
1833 +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
1837 + api_checknelems(L, n);
1838 + cl = luaF_newCclosure(L, n, getcurrenv(L));
1842 + setobj2n(L, &cl->c.upvalue[n], L->top+n);
1843 + setclvalue(L, L->top, cl);
1844 + lua_assert(iswhite(obj2gco(cl)));
1850 +LUA_API void lua_pushboolean (lua_State *L, int b) {
1852 + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
1858 +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
1860 + setpvalue(L->top, p);
1866 +LUA_API int lua_pushthread (lua_State *L) {
1868 + setthvalue(L, L->top, L);
1871 + return (G(L)->mainthread == L);
1877 +** get functions (Lua -> stack)
1881 +LUA_API void lua_gettable (lua_State *L, int idx) {
1884 + t = index2adr(L, idx);
1885 + api_checkvalidindex(L, t);
1886 + luaV_gettable(L, t, L->top - 1, L->top - 1);
1891 +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
1895 + t = index2adr(L, idx);
1896 + api_checkvalidindex(L, t);
1897 + setsvalue(L, &key, luaS_new(L, k));
1898 + luaV_gettable(L, t, &key, L->top);
1904 +LUA_API void lua_rawget (lua_State *L, int idx) {
1907 + t = index2adr(L, idx);
1908 + api_check(L, ttistable(t));
1909 + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
1914 +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
1917 + o = index2adr(L, idx);
1918 + api_check(L, ttistable(o));
1919 + setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
1925 +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
1928 + sethvalue(L, L->top, luaH_new(L, narray, nrec));
1934 +LUA_API int lua_getmetatable (lua_State *L, int objindex) {
1935 + const TValue *obj;
1939 + obj = index2adr(L, objindex);
1940 + switch (ttype(obj)) {
1942 + mt = hvalue(obj)->metatable;
1944 + case LUA_TUSERDATA:
1945 + mt = uvalue(obj)->metatable;
1948 + mt = G(L)->mt[ttype(obj)];
1954 + sethvalue(L, L->top, mt);
1963 +LUA_API void lua_getfenv (lua_State *L, int idx) {
1966 + o = index2adr(L, idx);
1967 + api_checkvalidindex(L, o);
1968 + switch (ttype(o)) {
1969 + case LUA_TFUNCTION:
1970 + sethvalue(L, L->top, clvalue(o)->c.env);
1972 + case LUA_TUSERDATA:
1973 + sethvalue(L, L->top, uvalue(o)->env);
1976 + setobj2s(L, L->top, gt(thvalue(o)));
1979 + setnilvalue(L->top);
1988 +** set functions (stack -> Lua)
1992 +LUA_API void lua_settable (lua_State *L, int idx) {
1995 + api_checknelems(L, 2);
1996 + t = index2adr(L, idx);
1997 + api_checkvalidindex(L, t);
1998 + luaV_settable(L, t, L->top - 2, L->top - 1);
1999 + L->top -= 2; /* pop index and value */
2004 +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
2008 + api_checknelems(L, 1);
2009 + t = index2adr(L, idx);
2010 + api_checkvalidindex(L, t);
2011 + setsvalue(L, &key, luaS_new(L, k));
2012 + luaV_settable(L, t, &key, L->top - 1);
2013 + L->top--; /* pop value */
2018 +LUA_API void lua_rawset (lua_State *L, int idx) {
2021 + api_checknelems(L, 2);
2022 + t = index2adr(L, idx);
2023 + api_check(L, ttistable(t));
2024 + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
2025 + luaC_barriert(L, hvalue(t), L->top-1);
2031 +LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
2034 + api_checknelems(L, 1);
2035 + o = index2adr(L, idx);
2036 + api_check(L, ttistable(o));
2037 + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
2038 + luaC_barriert(L, hvalue(o), L->top-1);
2044 +LUA_API int lua_setmetatable (lua_State *L, int objindex) {
2048 + api_checknelems(L, 1);
2049 + obj = index2adr(L, objindex);
2050 + api_checkvalidindex(L, obj);
2051 + if (ttisnil(L->top - 1))
2054 + api_check(L, ttistable(L->top - 1));
2055 + mt = hvalue(L->top - 1);
2057 + switch (ttype(obj)) {
2058 + case LUA_TTABLE: {
2059 + hvalue(obj)->metatable = mt;
2061 + luaC_objbarriert(L, hvalue(obj), mt);
2064 + case LUA_TUSERDATA: {
2065 + uvalue(obj)->metatable = mt;
2067 + luaC_objbarrier(L, rawuvalue(obj), mt);
2071 + G(L)->mt[ttype(obj)] = mt;
2081 +LUA_API int lua_setfenv (lua_State *L, int idx) {
2085 + api_checknelems(L, 1);
2086 + o = index2adr(L, idx);
2087 + api_checkvalidindex(L, o);
2088 + api_check(L, ttistable(L->top - 1));
2089 + switch (ttype(o)) {
2090 + case LUA_TFUNCTION:
2091 + clvalue(o)->c.env = hvalue(L->top - 1);
2093 + case LUA_TUSERDATA:
2094 + uvalue(o)->env = hvalue(L->top - 1);
2097 + sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
2103 + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
2111 +** `load' and `call' functions (run Lua code)
2115 +#define adjustresults(L,nres) \
2116 + { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
2119 +#define checkresults(L,na,nr) \
2120 + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
2123 +LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
2126 + api_checknelems(L, nargs+1);
2127 + checkresults(L, nargs, nresults);
2128 + func = L->top - (nargs+1);
2129 + luaD_call(L, func, nresults);
2130 + adjustresults(L, nresults);
2137 +** Execute a protected call.
2139 +struct CallS { /* data to `f_call' */
2145 +static void f_call (lua_State *L, void *ud) {
2146 + struct CallS *c = cast(struct CallS *, ud);
2147 + luaD_call(L, c->func, c->nresults);
2152 +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
2157 + api_checknelems(L, nargs+1);
2158 + checkresults(L, nargs, nresults);
2162 + StkId o = index2adr(L, errfunc);
2163 + api_checkvalidindex(L, o);
2164 + func = savestack(L, o);
2166 + c.func = L->top - (nargs+1); /* function to be called */
2167 + c.nresults = nresults;
2168 + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
2169 + adjustresults(L, nresults);
2176 +** Execute a protected C call.
2178 +struct CCallS { /* data to `f_Ccall' */
2179 + lua_CFunction func;
2184 +static void f_Ccall (lua_State *L, void *ud) {
2185 + struct CCallS *c = cast(struct CCallS *, ud);
2187 + cl = luaF_newCclosure(L, 0, getcurrenv(L));
2188 + cl->c.f = c->func;
2189 + setclvalue(L, L->top, cl); /* push function */
2191 + setpvalue(L->top, c->ud); /* push only argument */
2193 + luaD_call(L, L->top - 2, 0);
2197 +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
2203 + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
2209 +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
2210 + const char *chunkname) {
2214 + if (!chunkname) chunkname = "?";
2215 + luaZ_init(L, &z, reader, data);
2216 + status = luaD_protectedparser(L, &z, chunkname);
2222 +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
2226 + api_checknelems(L, 1);
2228 + if (isLfunction(o))
2229 + status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
2237 +LUA_API int lua_status (lua_State *L) {
2243 +** Garbage-collection function
2246 +LUA_API int lua_gc (lua_State *L, int what, int data) {
2252 + case LUA_GCSTOP: {
2253 + g->GCthreshold = MAX_LUMEM;
2256 + case LUA_GCRESTART: {
2257 + g->GCthreshold = g->totalbytes;
2260 + case LUA_GCCOLLECT: {
2264 + case LUA_GCCOUNT: {
2265 + /* GC values are expressed in Kbytes: #bytes/2^10 */
2266 + res = cast_int(g->totalbytes >> 10);
2269 + case LUA_GCCOUNTB: {
2270 + res = cast_int(g->totalbytes & 0x3ff);
2273 + case LUA_GCSTEP: {
2274 + lu_mem a = (cast(lu_mem, data) << 10);
2275 + if (a <= g->totalbytes)
2276 + g->GCthreshold = g->totalbytes - a;
2278 + g->GCthreshold = 0;
2279 + while (g->GCthreshold <= g->totalbytes) {
2281 + if (g->gcstate == GCSpause) { /* end of cycle? */
2282 + res = 1; /* signal it */
2288 + case LUA_GCSETPAUSE: {
2290 + g->gcpause = data;
2293 + case LUA_GCSETSTEPMUL: {
2294 + res = g->gcstepmul;
2295 + g->gcstepmul = data;
2298 + default: res = -1; /* invalid option */
2307 +** miscellaneous functions
2311 +LUA_API int lua_error (lua_State *L) {
2313 + api_checknelems(L, 1);
2316 + return 0; /* to avoid warnings */
2320 +LUA_API int lua_next (lua_State *L, int idx) {
2324 + t = index2adr(L, idx);
2325 + api_check(L, ttistable(t));
2326 + more = luaH_next(L, hvalue(t), L->top - 1);
2330 + else /* no more elements */
2331 + L->top -= 1; /* remove key */
2337 +LUA_API void lua_concat (lua_State *L, int n) {
2339 + api_checknelems(L, n);
2342 + luaV_concat(L, n, cast_int(L->top - L->base) - 1);
2345 + else if (n == 0) { /* push empty string */
2346 + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
2349 + /* else n == 1; nothing to do */
2354 +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
2357 + if (ud) *ud = G(L)->ud;
2358 + f = G(L)->frealloc;
2364 +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
2367 + G(L)->frealloc = f;
2372 +LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
2376 + u = luaS_newudata(L, size, getcurrenv(L));
2377 + setuvalue(L, L->top, u);
2386 +static const char *aux_upvalue (StkId fi, int n, TValue **val) {
2388 + if (!ttisfunction(fi)) return NULL;
2391 + if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
2392 + *val = &f->c.upvalue[n-1];
2396 + Proto *p = f->l.p;
2397 + if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
2398 + *val = f->l.upvals[n-1]->v;
2399 + return getstr(p->upvalues[n-1]);
2404 +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
2408 + name = aux_upvalue(index2adr(L, funcindex), n, &val);
2410 + setobj2s(L, L->top, val);
2418 +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
2423 + fi = index2adr(L, funcindex);
2424 + api_checknelems(L, 1);
2425 + name = aux_upvalue(fi, n, &val);
2428 + setobj(L, val, L->top);
2429 + luaC_barrier(L, clvalue(fi), L->top);
2436 +++ b/extensions/LUA/lua/lapi.h
2439 +** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $
2440 +** Auxiliary functions from Lua API
2441 +** See Copyright Notice in lua.h
2448 +#include "lobject.h"
2451 +LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
2455 +++ b/extensions/LUA/lua/lauxlib.c
2458 +** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $
2459 +** Auxiliary functions for building Lua libraries
2460 +** See Copyright Notice in lua.h
2463 +#include <stdarg.h>
2465 +#if !defined(__KERNEL__)
2469 +#include <stdlib.h>
2470 +#include <string.h>
2472 +#include <linux/ctype.h>
2473 +#include <linux/errno.h>
2474 +#include <linux/kernel.h>
2475 +#include <linux/slab.h>
2476 +#include <linux/string.h>
2479 +/* This file uses only the official API of Lua.
2480 +** Any function declared here could be written as an application function.
2488 +#include "lauxlib.h"
2491 +#define FREELIST_REF 0 /* free list of references */
2494 +/* convert a stack index to positive */
2495 +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
2496 + lua_gettop(L) + (i) + 1)
2500 +** {======================================================
2501 +** Error-report functions
2502 +** =======================================================
2506 +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
2508 + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
2509 + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
2510 + lua_getinfo(L, "n", &ar);
2511 + if (strcmp(ar.namewhat, "method") == 0) {
2512 + narg--; /* do not count `self' */
2513 + if (narg == 0) /* error is in the self argument itself? */
2514 + return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
2515 + ar.name, extramsg);
2517 + if (ar.name == NULL)
2519 + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
2520 + narg, ar.name, extramsg);
2524 +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
2525 + const char *msg = lua_pushfstring(L, "%s expected, got %s",
2526 + tname, luaL_typename(L, narg));
2527 + return luaL_argerror(L, narg, msg);
2531 +static void tag_error (lua_State *L, int narg, int tag) {
2532 + luaL_typerror(L, narg, lua_typename(L, tag));
2536 +LUALIB_API void luaL_where (lua_State *L, int level) {
2538 + if (lua_getstack(L, level, &ar)) { /* check function at level */
2539 + lua_getinfo(L, "Sl", &ar); /* get info about it */
2540 + if (ar.currentline > 0) { /* is there info? */
2541 + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
2545 + lua_pushliteral(L, ""); /* else, no information available... */
2549 +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
2551 + va_start(argp, fmt);
2553 + lua_pushvfstring(L, fmt, argp);
2556 + return lua_error(L);
2559 +/* }====================================================== */
2562 +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
2563 + const char *const lst[]) {
2564 + const char *name = (def) ? luaL_optstring(L, narg, def) :
2565 + luaL_checkstring(L, narg);
2567 + for (i=0; lst[i]; i++)
2568 + if (strcmp(lst[i], name) == 0)
2570 + return luaL_argerror(L, narg,
2571 + lua_pushfstring(L, "invalid option " LUA_QS, name));
2575 +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
2576 + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
2577 + if (!lua_isnil(L, -1)) /* name already in use? */
2578 + return 0; /* leave previous value on top, but return 0 */
2580 + lua_newtable(L); /* create metatable */
2581 + lua_pushvalue(L, -1);
2582 + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
2587 +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
2588 + void *p = lua_touserdata(L, ud);
2589 + if (p != NULL) { /* value is a userdata? */
2590 + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
2591 + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
2592 + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
2593 + lua_pop(L, 2); /* remove both metatables */
2598 + luaL_typerror(L, ud, tname); /* else error */
2599 + return NULL; /* to avoid warnings */
2603 +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
2604 + if (!lua_checkstack(L, space))
2605 + luaL_error(L, "stack overflow (%s)", mes);
2609 +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
2610 + if (lua_type(L, narg) != t)
2611 + tag_error(L, narg, t);
2615 +LUALIB_API void luaL_checkany (lua_State *L, int narg) {
2616 + if (lua_type(L, narg) == LUA_TNONE)
2617 + luaL_argerror(L, narg, "value expected");
2621 +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
2622 + const char *s = lua_tolstring(L, narg, len);
2623 + if (!s) tag_error(L, narg, LUA_TSTRING);
2628 +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
2629 + const char *def, size_t *len) {
2630 + if (lua_isnoneornil(L, narg)) {
2632 + *len = (def ? strlen(def) : 0);
2635 + else return luaL_checklstring(L, narg, len);
2639 +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
2640 + lua_Number d = lua_tonumber(L, narg);
2641 + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
2642 + tag_error(L, narg, LUA_TNUMBER);
2647 +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
2648 + return luaL_opt(L, luaL_checknumber, narg, def);
2652 +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
2653 + lua_Integer d = lua_tointeger(L, narg);
2654 + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
2655 + tag_error(L, narg, LUA_TNUMBER);
2660 +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
2661 + lua_Integer def) {
2662 + return luaL_opt(L, luaL_checkinteger, narg, def);
2666 +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
2667 + if (!lua_getmetatable(L, obj)) /* no metatable? */
2669 + lua_pushstring(L, event);
2670 + lua_rawget(L, -2);
2671 + if (lua_isnil(L, -1)) {
2672 + lua_pop(L, 2); /* remove metatable and metafield */
2676 + lua_remove(L, -2); /* remove only metatable */
2682 +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
2683 + obj = abs_index(L, obj);
2684 + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
2686 + lua_pushvalue(L, obj);
2687 + lua_call(L, 1, 1);
2692 +LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
2693 + const luaL_Reg *l) {
2694 + luaI_openlib(L, libname, l, 0);
2698 +static int libsize (const luaL_Reg *l) {
2700 + for (; l->name; l++) size++;
2705 +LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
2706 + const luaL_Reg *l, int nup) {
2708 + int size = libsize(l);
2709 + /* check whether lib already exists */
2710 + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
2711 + lua_getfield(L, -1, libname); /* get _LOADED[libname] */
2712 + if (!lua_istable(L, -1)) { /* not found? */
2713 + lua_pop(L, 1); /* remove previous result */
2714 + /* try global variable (and create one if it does not exist) */
2715 + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
2716 + luaL_error(L, "name conflict for module " LUA_QS, libname);
2717 + lua_pushvalue(L, -1);
2718 + lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
2720 + lua_remove(L, -2); /* remove _LOADED table */
2721 + lua_insert(L, -(nup+1)); /* move library table to below upvalues */
2723 + for (; l->name; l++) {
2725 + for (i=0; i<nup; i++) /* copy upvalues to the top */
2726 + lua_pushvalue(L, -nup);
2727 + lua_pushcclosure(L, l->func, nup);
2728 + lua_setfield(L, -(nup+2), l->name);
2730 + lua_pop(L, nup); /* remove upvalues */
2736 +** {======================================================
2737 +** getn-setn: size for arrays
2738 +** =======================================================
2741 +#if defined(LUA_COMPAT_GETN)
2743 +static int checkint (lua_State *L, int topop) {
2744 + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
2745 + lua_pop(L, topop);
2750 +static void getsizes (lua_State *L) {
2751 + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
2752 + if (lua_isnil(L, -1)) { /* no `size' table? */
2753 + lua_pop(L, 1); /* remove nil */
2754 + lua_newtable(L); /* create it */
2755 + lua_pushvalue(L, -1); /* `size' will be its own metatable */
2756 + lua_setmetatable(L, -2);
2757 + lua_pushliteral(L, "kv");
2758 + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
2759 + lua_pushvalue(L, -1);
2760 + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
2765 +LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
2766 + t = abs_index(L, t);
2767 + lua_pushliteral(L, "n");
2769 + if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
2770 + lua_pushliteral(L, "n"); /* use it */
2771 + lua_pushinteger(L, n);
2774 + else { /* use `sizes' */
2776 + lua_pushvalue(L, t);
2777 + lua_pushinteger(L, n);
2778 + lua_rawset(L, -3); /* sizes[t] = n */
2779 + lua_pop(L, 1); /* remove `sizes' */
2784 +LUALIB_API int luaL_getn (lua_State *L, int t) {
2786 + t = abs_index(L, t);
2787 + lua_pushliteral(L, "n"); /* try t.n */
2789 + if ((n = checkint(L, 1)) >= 0) return n;
2790 + getsizes(L); /* else try sizes[t] */
2791 + lua_pushvalue(L, t);
2792 + lua_rawget(L, -2);
2793 + if ((n = checkint(L, 2)) >= 0) return n;
2794 + return (int)lua_objlen(L, t);
2799 +/* }====================================================== */
2803 +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
2806 + size_t l = strlen(p);
2807 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
2808 + if(!b) luaL_error(L, "luaL_gsub: cannot allocate memory");
2809 + luaL_buffinit(L, b);
2810 + while ((wild = strstr(s, p)) != NULL) {
2811 + luaL_addlstring(b, s, wild - s); /* push prefix */
2812 + luaL_addstring(b, r); /* push replacement in place of pattern */
2813 + s = wild + l; /* continue after `p' */
2815 + luaL_addstring(b, s); /* push last suffix */
2816 + luaL_pushresult(b);
2818 + return lua_tostring(L, -1);
2822 +LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
2823 + const char *fname, int szhint) {
2825 + lua_pushvalue(L, idx);
2827 + e = strchr(fname, '.');
2828 + if (e == NULL) e = fname + strlen(fname);
2829 + lua_pushlstring(L, fname, e - fname);
2830 + lua_rawget(L, -2);
2831 + if (lua_isnil(L, -1)) { /* no such field? */
2832 + lua_pop(L, 1); /* remove this nil */
2833 + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
2834 + lua_pushlstring(L, fname, e - fname);
2835 + lua_pushvalue(L, -2);
2836 + lua_settable(L, -4); /* set new table into field */
2838 + else if (!lua_istable(L, -1)) { /* field has a non-table value? */
2839 + lua_pop(L, 2); /* remove table and value */
2840 + return fname; /* return problematic part of the name */
2842 + lua_remove(L, -2); /* remove previous table */
2844 + } while (*e == '.');
2851 +** {======================================================
2852 +** Generic Buffer manipulation
2853 +** =======================================================
2857 +#define bufflen(B) ((B)->p - (B)->buffer)
2858 +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
2860 +#define LIMIT (LUA_MINSTACK/2)
2863 +static int emptybuffer (luaL_Buffer *B) {
2864 + size_t l = bufflen(B);
2865 + if (l == 0) return 0; /* put nothing on stack */
2867 + lua_pushlstring(B->L, B->buffer, l);
2875 +static void adjuststack (luaL_Buffer *B) {
2877 + lua_State *L = B->L;
2878 + int toget = 1; /* number of levels to concat */
2879 + size_t toplen = lua_strlen(L, -1);
2881 + size_t l = lua_strlen(L, -(toget+1));
2882 + if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
2887 + } while (toget < B->lvl);
2888 + lua_concat(L, toget);
2889 + B->lvl = B->lvl - toget + 1;
2894 +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
2895 + if (emptybuffer(B))
2901 +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
2903 + luaL_addchar(B, *s++);
2907 +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
2908 + luaL_addlstring(B, s, strlen(s));
2912 +LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
2914 + lua_concat(B->L, B->lvl);
2919 +LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
2920 + lua_State *L = B->L;
2922 + const char *s = lua_tolstring(L, -1, &vl);
2923 + if (vl <= bufffree(B)) { /* fit into buffer? */
2924 + memcpy(B->p, s, vl); /* put it there */
2926 + lua_pop(L, 1); /* remove from stack */
2929 + if (emptybuffer(B))
2930 + lua_insert(L, -2); /* put buffer before new value */
2931 + B->lvl++; /* add new value into B stack */
2937 +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
2943 +/* }====================================================== */
2946 +LUALIB_API int luaL_ref (lua_State *L, int t) {
2948 + t = abs_index(L, t);
2949 + if (lua_isnil(L, -1)) {
2950 + lua_pop(L, 1); /* remove from stack */
2951 + return LUA_REFNIL; /* `nil' has a unique fixed reference */
2953 + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
2954 + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
2955 + lua_pop(L, 1); /* remove it from stack */
2956 + if (ref != 0) { /* any free element? */
2957 + lua_rawgeti(L, t, ref); /* remove it from list */
2958 + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
2960 + else { /* no free elements */
2961 + ref = (int)lua_objlen(L, t);
2962 + ref++; /* create new reference */
2964 + lua_rawseti(L, t, ref);
2969 +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
2971 + t = abs_index(L, t);
2972 + lua_rawgeti(L, t, FREELIST_REF);
2973 + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
2974 + lua_pushinteger(L, ref);
2975 + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
2982 +** {======================================================
2984 +** =======================================================
2987 +#if !defined(__KERNEL__)
2988 +typedef struct LoadF {
2991 + char buff[LUAL_BUFFERSIZE];
2995 +static const char *getF (lua_State *L, void *ud, size_t *size) {
2996 + LoadF *lf = (LoadF *)ud;
2998 + if (lf->extraline) {
2999 + lf->extraline = 0;
3003 + if (feof(lf->f)) return NULL;
3004 + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
3005 + return (*size > 0) ? lf->buff : NULL;
3009 +static int errfile (lua_State *L, const char *what, int fnameindex) {
3010 + const char *serr = strerror(errno);
3011 + const char *filename = lua_tostring(L, fnameindex) + 1;
3012 + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
3013 + lua_remove(L, fnameindex);
3014 + return LUA_ERRFILE;
3018 +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
3020 + int status, readstatus;
3022 + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
3024 + if (filename == NULL) {
3025 + lua_pushliteral(L, "=stdin");
3029 + lua_pushfstring(L, "@%s", filename);
3030 + lf.f = fopen(filename, "r");
3031 + if (lf.f == NULL) return errfile(L, "open", fnameindex);
3034 + if (c == '#') { /* Unix exec. file? */
3036 + while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
3037 + if (c == '\n') c = getc(lf.f);
3039 + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
3040 + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
3041 + if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
3042 + /* skip eventual `#!...' */
3043 + while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
3047 + status = lua_load(L, getF, &lf, lua_tostring(L, -1));
3048 + readstatus = ferror(lf.f);
3049 + if (filename) fclose(lf.f); /* close file (even in case of errors) */
3051 + lua_settop(L, fnameindex); /* ignore results from `lua_load' */
3052 + return errfile(L, "read", fnameindex);
3054 + lua_remove(L, fnameindex);
3059 +typedef struct LoadS {
3065 +static const char *getS (lua_State *L, void *ud, size_t *size) {
3066 + LoadS *ls = (LoadS *)ud;
3068 + if (ls->size == 0) return NULL;
3075 +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
3076 + const char *name) {
3080 + return lua_load(L, getS, &ls, name);
3084 +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
3085 + return luaL_loadbuffer(L, s, strlen(s), s);
3090 +/* }====================================================== */
3093 +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
3097 +#if !defined(__KERNEL__)
3105 +#if !defined(__KERNEL__)
3106 + return realloc(ptr, nsize);
3108 + return krealloc(ptr, nsize, GFP_ATOMIC);
3113 +static int lpanic (lua_State *L) {
3114 + (void)L; /* to avoid warnings */
3115 +#if !defined(__KERNEL__)
3116 + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
3118 + printk( "PANIC: unprotected error in call to Lua API (%s)\n",
3120 + lua_tostring(L, -1));
3125 +LUALIB_API lua_State *luaL_newstate (void) {
3126 + lua_State *L = lua_newstate(l_alloc, NULL);
3127 + if (L) lua_atpanic(L, &lpanic);
3132 +++ b/extensions/LUA/lua/lauxlib.h
3135 +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
3136 +** Auxiliary functions for building Lua libraries
3137 +** See Copyright Notice in lua.h
3145 +#include <stddef.h>
3146 +#include <linux/slab.h> /* for kmalloc and kfree when allocating luaL_Buffer */
3148 +#if !defined(__KERNEL__)
3155 +#if defined(LUA_COMPAT_GETN)
3156 +LUALIB_API int (luaL_getn) (lua_State *L, int t);
3157 +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
3159 +#define luaL_getn(L,i) ((int)lua_objlen(L, i))
3160 +#define luaL_setn(L,i,j) ((void)0) /* no op! */
3163 +#if defined(LUA_COMPAT_OPENLIB)
3164 +#define luaI_openlib luaL_openlib
3168 +/* extra error code for `luaL_load' */
3169 +#define LUA_ERRFILE (LUA_ERRERR+1)
3172 +typedef struct luaL_Reg {
3174 + lua_CFunction func;
3179 +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
3180 + const luaL_Reg *l, int nup);
3181 +LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
3182 + const luaL_Reg *l);
3183 +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
3184 +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
3185 +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
3186 +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
3187 +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
3189 +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
3190 + const char *def, size_t *l);
3191 +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
3192 +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
3194 +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
3195 +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
3198 +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
3199 +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
3200 +LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
3202 +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
3203 +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
3205 +LUALIB_API void (luaL_where) (lua_State *L, int lvl);
3206 +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
3208 +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
3209 + const char *const lst[]);
3211 +LUALIB_API int (luaL_ref) (lua_State *L, int t);
3212 +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
3214 +#if !defined(__KERNEL__)
3215 +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
3218 +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
3219 + const char *name);
3220 +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
3222 +LUALIB_API lua_State *(luaL_newstate) (void);
3225 +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
3228 +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
3229 + const char *fname, int szhint);
3235 +** ===============================================================
3236 +** some useful macros
3237 +** ===============================================================
3240 +#define luaL_argcheck(L, cond,numarg,extramsg) \
3241 + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
3242 +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
3243 +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
3244 +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
3245 +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
3246 +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
3247 +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
3249 +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
3251 +#if !defined(__KERNEL__)
3252 +#define luaL_dofile(L, fn) \
3253 + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
3256 +#define luaL_dostring(L, s) \
3257 + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
3259 +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
3261 +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
3264 +** {======================================================
3265 +** Generic Buffer manipulation
3266 +** =======================================================
3271 +typedef struct luaL_Buffer {
3272 + char *p; /* current position in buffer */
3273 + int lvl; /* number of strings in the stack (level) */
3275 + char buffer[LUAL_BUFFERSIZE];
3278 +#define luaL_addchar(B,c) \
3279 + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
3280 + (*(B)->p++ = (char)(c)))
3282 +/* compatibility only */
3283 +#define luaL_putchar(B,c) luaL_addchar(B,c)
3285 +#define luaL_addsize(B,n) ((B)->p += (n))
3288 +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
3289 +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
3290 +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
3291 +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
3292 +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
3293 +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
3296 +/* }====================================================== */
3299 +/* compatibility with ref system */
3301 +/* pre-defined references */
3302 +#define LUA_NOREF (-2)
3303 +#define LUA_REFNIL (-1)
3305 +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
3306 + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
3308 +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
3310 +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
3313 +#define luaL_reg luaL_Reg
3319 +++ b/extensions/LUA/lua/lbaselib.c
3322 +** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
3324 +** See Copyright Notice in lua.h
3328 +#include <linux/kernel.h>
3329 +#include <linux/ctype.h>
3330 +#include <linux/string.h>
3337 +#include "lauxlib.h"
3338 +#include "lualib.h"
3344 +** If your system does not support `stdout', you can just remove this function.
3345 +** If you need, you can define your own `print' function, following this
3346 +** model but changing `fputs' to put the strings at a proper place
3347 +** (a console window or a log file, for instance).
3349 +static int luaB_print (lua_State *L) {
3350 + int n = lua_gettop(L); /* number of arguments */
3352 + lua_getglobal(L, "tostring");
3353 + for (i=1; i<=n; i++) {
3355 + lua_pushvalue(L, -1); /* function to be called */
3356 + lua_pushvalue(L, i); /* value to print */
3357 + lua_call(L, 1, 1);
3358 + s = lua_tostring(L, -1); /* get result */
3360 + return luaL_error(L, LUA_QL("tostring") " must return a string to "
3362 + printk(KERN_INFO "LUA[print]: %s", s);
3363 + lua_pop(L, 1); /* pop result */
3369 +static int luaB_tonumber (lua_State *L) {
3370 + int base = luaL_optint(L, 2, 10);
3371 + if (base == 10) { /* standard conversion */
3372 + luaL_checkany(L, 1);
3373 + if (lua_isnumber(L, 1)) {
3374 + lua_pushnumber(L, lua_tonumber(L, 1));
3379 + const char *s1 = luaL_checkstring(L, 1);
3382 + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
3383 + n = simple_strtoul(s1, &s2, base);
3384 + if (s1 != s2) { /* at least one valid digit? */
3385 + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
3386 + if (*s2 == '\0') { /* no invalid trailing characters? */
3387 + lua_pushnumber(L, (lua_Number)n);
3392 + lua_pushnil(L); /* else not a number */
3397 +static int luaB_error (lua_State *L) {
3398 + int level = luaL_optint(L, 2, 1);
3400 + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
3401 + luaL_where(L, level);
3402 + lua_pushvalue(L, 1);
3405 + return lua_error(L);
3409 +static int luaB_getmetatable (lua_State *L) {
3410 + luaL_checkany(L, 1);
3411 + if (!lua_getmetatable(L, 1)) {
3413 + return 1; /* no metatable */
3415 + luaL_getmetafield(L, 1, "__metatable");
3416 + return 1; /* returns either __metatable field (if present) or metatable */
3420 +static int luaB_setmetatable (lua_State *L) {
3421 + int t = lua_type(L, 2);
3422 + luaL_checktype(L, 1, LUA_TTABLE);
3423 + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
3424 + "nil or table expected");
3425 + if (luaL_getmetafield(L, 1, "__metatable"))
3426 + luaL_error(L, "cannot change a protected metatable");
3428 + lua_setmetatable(L, 1);
3433 +static void getfunc (lua_State *L, int opt) {
3434 + if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
3437 + int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
3438 + luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
3439 + if (lua_getstack(L, level, &ar) == 0)
3440 + luaL_argerror(L, 1, "invalid level");
3441 + lua_getinfo(L, "f", &ar);
3442 + if (lua_isnil(L, -1))
3443 + luaL_error(L, "no function environment for tail call at level %d",
3449 +static int luaB_getfenv (lua_State *L) {
3451 + if (lua_iscfunction(L, -1)) /* is a C function? */
3452 + lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
3454 + lua_getfenv(L, -1);
3459 +static int luaB_setfenv (lua_State *L) {
3460 + luaL_checktype(L, 2, LUA_TTABLE);
3462 + lua_pushvalue(L, 2);
3463 + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
3464 + /* change environment of current thread */
3465 + lua_pushthread(L);
3466 + lua_insert(L, -2);
3467 + lua_setfenv(L, -2);
3470 + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
3472 + LUA_QL("setfenv") " cannot change environment of given object");
3477 +static int luaB_rawequal (lua_State *L) {
3478 + luaL_checkany(L, 1);
3479 + luaL_checkany(L, 2);
3480 + lua_pushboolean(L, lua_rawequal(L, 1, 2));
3485 +static int luaB_rawget (lua_State *L) {
3486 + luaL_checktype(L, 1, LUA_TTABLE);
3487 + luaL_checkany(L, 2);
3493 +static int luaB_rawset (lua_State *L) {
3494 + luaL_checktype(L, 1, LUA_TTABLE);
3495 + luaL_checkany(L, 2);
3496 + luaL_checkany(L, 3);
3503 +static int luaB_gcinfo (lua_State *L) {
3504 + lua_pushinteger(L, lua_getgccount(L));
3508 +static int luaB_collectgarbage (lua_State *L) {
3509 + static const char *const opts[] = {"stop", "restart", "collect",
3510 + "count", "step", "setpause", "setstepmul", NULL};
3511 + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
3512 + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
3513 + int o = luaL_checkoption(L, 1, "collect", opts);
3514 + int ex = luaL_optint(L, 2, 0);
3515 + int res = lua_gc(L, optsnum[o], ex);
3516 + switch (optsnum[o]) {
3517 + case LUA_GCCOUNT: {
3518 + int b = lua_gc(L, LUA_GCCOUNTB, 0);
3519 + lua_pushnumber(L, res + ((lua_Number)b/1024));
3522 + case LUA_GCSTEP: {
3523 + lua_pushboolean(L, res);
3527 + lua_pushnumber(L, res);
3534 +static int luaB_type (lua_State *L) {
3535 + luaL_checkany(L, 1);
3536 + lua_pushstring(L, luaL_typename(L, 1));
3541 +static int luaB_next (lua_State *L) {
3542 + luaL_checktype(L, 1, LUA_TTABLE);
3543 + lua_settop(L, 2); /* create a 2nd argument if there isn't one */
3544 + if (lua_next(L, 1))
3553 +static int luaB_pairs (lua_State *L) {
3554 + luaL_checktype(L, 1, LUA_TTABLE);
3555 + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
3556 + lua_pushvalue(L, 1); /* state, */
3557 + lua_pushnil(L); /* and initial value */
3562 +static int ipairsaux (lua_State *L) {
3563 + int i = luaL_checkint(L, 2);
3564 + luaL_checktype(L, 1, LUA_TTABLE);
3565 + i++; /* next value */
3566 + lua_pushinteger(L, i);
3567 + lua_rawgeti(L, 1, i);
3568 + return (lua_isnil(L, -1)) ? 0 : 2;
3572 +static int luaB_ipairs (lua_State *L) {
3573 + luaL_checktype(L, 1, LUA_TTABLE);
3574 + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
3575 + lua_pushvalue(L, 1); /* state, */
3576 + lua_pushinteger(L, 0); /* and initial value */
3581 +static int load_aux (lua_State *L, int status) {
3582 + if (status == 0) /* OK? */
3586 + lua_insert(L, -2); /* put before error message */
3587 + return 2; /* return nil plus error message */
3592 +static int luaB_loadstring (lua_State *L) {
3594 + const char *s = luaL_checklstring(L, 1, &l);
3595 + const char *chunkname = luaL_optstring(L, 2, s);
3596 + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
3600 +static int luaB_loadfile (lua_State *L) {
3601 + const char *fname = luaL_optstring(L, 1, NULL);
3602 + return load_aux(L, luaL_loadfile(L, fname));
3607 +** Reader for generic `load' function: `lua_load' uses the
3608 +** stack for internal stuff, so the reader cannot change the
3609 +** stack top. Instead, it keeps its resulting string in a
3610 +** reserved slot inside the stack.
3612 +static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
3613 + (void)ud; /* to avoid warnings */
3614 + luaL_checkstack(L, 2, "too many nested functions");
3615 + lua_pushvalue(L, 1); /* get function */
3616 + lua_call(L, 0, 1); /* call it */
3617 + if (lua_isnil(L, -1)) {
3621 + else if (lua_isstring(L, -1)) {
3622 + lua_replace(L, 3); /* save string in a reserved stack slot */
3623 + return lua_tolstring(L, 3, size);
3625 + else luaL_error(L, "reader function must return a string");
3626 + return NULL; /* to avoid warnings */
3630 +static int luaB_load (lua_State *L) {
3632 + const char *cname = luaL_optstring(L, 2, "=(load)");
3633 + luaL_checktype(L, 1, LUA_TFUNCTION);
3634 + lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
3635 + status = lua_load(L, generic_reader, NULL, cname);
3636 + return load_aux(L, status);
3640 +static int luaB_dofile (lua_State *L) {
3641 + const char *fname = luaL_optstring(L, 1, NULL);
3642 + int n = lua_gettop(L);
3643 + if (luaL_loadfile(L, fname) != 0) lua_error(L);
3644 + lua_call(L, 0, LUA_MULTRET);
3645 + return lua_gettop(L) - n;
3649 +static int luaB_assert (lua_State *L) {
3650 + luaL_checkany(L, 1);
3651 + if (!lua_toboolean(L, 1))
3652 + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
3653 + return lua_gettop(L);
3657 +static int luaB_unpack (lua_State *L) {
3659 + luaL_checktype(L, 1, LUA_TTABLE);
3660 + i = luaL_optint(L, 2, 1);
3661 + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
3662 + if (i > e) return 0; /* empty range */
3663 + n = e - i + 1; /* number of elements */
3664 + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
3665 + return luaL_error(L, "too many results to unpack");
3666 + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
3667 + while (i++ < e) /* push arg[i + 1...e] */
3668 + lua_rawgeti(L, 1, i);
3673 +static int luaB_select (lua_State *L) {
3674 + int n = lua_gettop(L);
3675 + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
3676 + lua_pushinteger(L, n-1);
3680 + int i = luaL_checkint(L, 1);
3681 + if (i < 0) i = n + i;
3682 + else if (i > n) i = n;
3683 + luaL_argcheck(L, 1 <= i, 1, "index out of range");
3689 +static int luaB_pcall (lua_State *L) {
3691 + luaL_checkany(L, 1);
3692 + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
3693 + lua_pushboolean(L, (status == 0));
3695 + return lua_gettop(L); /* return status + all results */
3699 +static int luaB_xpcall (lua_State *L) {
3701 + luaL_checkany(L, 2);
3703 + lua_insert(L, 1); /* put error function under function to be called */
3704 + status = lua_pcall(L, 0, LUA_MULTRET, 1);
3705 + lua_pushboolean(L, (status == 0));
3706 + lua_replace(L, 1);
3707 + return lua_gettop(L); /* return status + all results */
3711 +static int luaB_tostring (lua_State *L) {
3712 + luaL_checkany(L, 1);
3713 + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
3714 + return 1; /* use its value */
3715 + switch (lua_type(L, 1)) {
3717 + lua_pushstring(L, lua_tostring(L, 1));
3720 + lua_pushvalue(L, 1);
3722 + case LUA_TBOOLEAN:
3723 + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
3726 + lua_pushliteral(L, "nil");
3729 + lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
3736 +static int luaB_newproxy (lua_State *L) {
3738 + lua_newuserdata(L, 0); /* create proxy */
3739 + if (lua_toboolean(L, 1) == 0)
3740 + return 1; /* no metatable */
3741 + else if (lua_isboolean(L, 1)) {
3742 + lua_newtable(L); /* create a new metatable `m' ... */
3743 + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
3744 + lua_pushboolean(L, 1);
3745 + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
3748 + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
3749 + if (lua_getmetatable(L, 1)) {
3750 + lua_rawget(L, lua_upvalueindex(1));
3751 + validproxy = lua_toboolean(L, -1);
3752 + lua_pop(L, 1); /* remove value */
3754 + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
3755 + lua_getmetatable(L, 1); /* metatable is valid; get it */
3757 + lua_setmetatable(L, 2);
3762 +static const luaL_Reg base_funcs[] = {
3763 + {"assert", luaB_assert},
3764 + {"collectgarbage", luaB_collectgarbage},
3765 +// {"dofile", luaB_dofile},
3766 + {"error", luaB_error},
3767 + {"gcinfo", luaB_gcinfo},
3768 + {"getfenv", luaB_getfenv},
3769 + {"getmetatable", luaB_getmetatable},
3770 +// {"loadfile", luaB_loadfile},
3771 + {"load", luaB_load},
3772 + {"loadstring", luaB_loadstring},
3773 + {"next", luaB_next},
3774 + {"pcall", luaB_pcall},
3775 + {"print", luaB_print},
3776 + {"rawequal", luaB_rawequal},
3777 + {"rawget", luaB_rawget},
3778 + {"rawset", luaB_rawset},
3779 + {"select", luaB_select},
3780 + {"setfenv", luaB_setfenv},
3781 + {"setmetatable", luaB_setmetatable},
3782 + {"tonumber", luaB_tonumber},
3783 + {"tostring", luaB_tostring},
3784 + {"type", luaB_type},
3785 + {"unpack", luaB_unpack},
3786 + {"xpcall", luaB_xpcall},
3792 +** {======================================================
3793 +** Coroutine library
3794 +** =======================================================
3797 +#define CO_RUN 0 /* running */
3798 +#define CO_SUS 1 /* suspended */
3799 +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
3802 +static const char *const statnames[] =
3803 + {"running", "suspended", "normal", "dead"};
3805 +static int costatus (lua_State *L, lua_State *co) {
3806 + if (L == co) return CO_RUN;
3807 + switch (lua_status(co)) {
3812 + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
3813 + return CO_NOR; /* it is running */
3814 + else if (lua_gettop(co) == 0)
3817 + return CO_SUS; /* initial state */
3819 + default: /* some error occured */
3825 +static int luaB_costatus (lua_State *L) {
3826 + lua_State *co = lua_tothread(L, 1);
3827 + luaL_argcheck(L, co, 1, "coroutine expected");
3828 + lua_pushstring(L, statnames[costatus(L, co)]);
3833 +static int auxresume (lua_State *L, lua_State *co, int narg) {
3834 + int status = costatus(L, co);
3835 + if (!lua_checkstack(co, narg))
3836 + luaL_error(L, "too many arguments to resume");
3837 + if (status != CO_SUS) {
3838 + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
3839 + return -1; /* error flag */
3841 + lua_xmove(L, co, narg);
3842 + lua_setlevel(L, co);
3843 + status = lua_resume(co, narg);
3844 + if (status == 0 || status == LUA_YIELD) {
3845 + int nres = lua_gettop(co);
3846 + if (!lua_checkstack(L, nres + 1))
3847 + luaL_error(L, "too many results to resume");
3848 + lua_xmove(co, L, nres); /* move yielded values */
3852 + lua_xmove(co, L, 1); /* move error message */
3853 + return -1; /* error flag */
3858 +static int luaB_coresume (lua_State *L) {
3859 + lua_State *co = lua_tothread(L, 1);
3861 + luaL_argcheck(L, co, 1, "coroutine expected");
3862 + r = auxresume(L, co, lua_gettop(L) - 1);
3864 + lua_pushboolean(L, 0);
3865 + lua_insert(L, -2);
3866 + return 2; /* return false + error message */
3869 + lua_pushboolean(L, 1);
3870 + lua_insert(L, -(r + 1));
3871 + return r + 1; /* return true + `resume' returns */
3876 +static int luaB_auxwrap (lua_State *L) {
3877 + lua_State *co = lua_tothread(L, lua_upvalueindex(1));
3878 + int r = auxresume(L, co, lua_gettop(L));
3880 + if (lua_isstring(L, -1)) { /* error object is a string? */
3881 + luaL_where(L, 1); /* add extra info */
3882 + lua_insert(L, -2);
3885 + lua_error(L); /* propagate error */
3891 +static int luaB_cocreate (lua_State *L) {
3892 + lua_State *NL = lua_newthread(L);
3893 + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
3894 + "Lua function expected");
3895 + lua_pushvalue(L, 1); /* move function to top */
3896 + lua_xmove(L, NL, 1); /* move function from L to NL */
3901 +static int luaB_cowrap (lua_State *L) {
3903 + lua_pushcclosure(L, luaB_auxwrap, 1);
3908 +static int luaB_yield (lua_State *L) {
3909 + return lua_yield(L, lua_gettop(L));
3913 +static int luaB_corunning (lua_State *L) {
3914 + if (lua_pushthread(L))
3915 + lua_pushnil(L); /* main thread is not a coroutine */
3920 +static const luaL_Reg co_funcs[] = {
3921 + {"create", luaB_cocreate},
3922 + {"resume", luaB_coresume},
3923 + {"running", luaB_corunning},
3924 + {"status", luaB_costatus},
3925 + {"wrap", luaB_cowrap},
3926 + {"yield", luaB_yield},
3930 +/* }====================================================== */
3933 +static void auxopen (lua_State *L, const char *name,
3934 + lua_CFunction f, lua_CFunction u) {
3935 + lua_pushcfunction(L, u);
3936 + lua_pushcclosure(L, f, 1);
3937 + lua_setfield(L, -2, name);
3941 +static void base_open (lua_State *L) {
3942 + /* set global _G */
3943 + lua_pushvalue(L, LUA_GLOBALSINDEX);
3944 + lua_setglobal(L, "_G");
3945 + /* open lib into global table */
3946 + luaL_register(L, "_G", base_funcs);
3947 + lua_pushliteral(L, LUA_VERSION);
3948 + lua_setglobal(L, "_VERSION"); /* set global _VERSION */
3949 + /* `ipairs' and `pairs' need auxliliary functions as upvalues */
3950 + auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
3951 + auxopen(L, "pairs", luaB_pairs, luaB_next);
3952 + /* `newproxy' needs a weaktable as upvalue */
3953 + lua_createtable(L, 0, 1); /* new table `w' */
3954 + lua_pushvalue(L, -1); /* `w' will be its own metatable */
3955 + lua_setmetatable(L, -2);
3956 + lua_pushliteral(L, "kv");
3957 + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
3958 + lua_pushcclosure(L, luaB_newproxy, 1);
3959 + lua_setglobal(L, "newproxy"); /* set global `newproxy' */
3963 +LUALIB_API int luaopen_base (lua_State *L) {
3965 + luaL_register(L, LUA_COLIBNAME, co_funcs);
3969 +++ b/extensions/LUA/lua/lcode.c
3972 +** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
3973 +** Code generator for Lua
3974 +** See Copyright Notice in lua.h
3977 +#include <stdlib.h>
3985 +#include "ldebug.h"
3990 +#include "lobject.h"
3991 +#include "lopcodes.h"
3992 +#include "lparser.h"
3993 +#include "ltable.h"
3996 +#define hasjumps(e) ((e)->t != (e)->f)
3999 +static int isnumeral(expdesc *e) {
4000 + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
4004 +void luaK_nil (FuncState *fs, int from, int n) {
4005 + Instruction *previous;
4006 + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
4007 + if (fs->pc == 0) { /* function start? */
4008 + if (from >= fs->nactvar)
4009 + return; /* positions are already clean */
4012 + previous = &fs->f->code[fs->pc-1];
4013 + if (GET_OPCODE(*previous) == OP_LOADNIL) {
4014 + int pfrom = GETARG_A(*previous);
4015 + int pto = GETARG_B(*previous);
4016 + if (pfrom <= from && from <= pto+1) { /* can connect both? */
4017 + if (from+n-1 > pto)
4018 + SETARG_B(*previous, from+n-1);
4024 + luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
4028 +int luaK_jump (FuncState *fs) {
4029 + int jpc = fs->jpc; /* save list of jumps to here */
4031 + fs->jpc = NO_JUMP;
4032 + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
4033 + luaK_concat(fs, &j, jpc); /* keep them on hold */
4038 +void luaK_ret (FuncState *fs, int first, int nret) {
4039 + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
4043 +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
4044 + luaK_codeABC(fs, op, A, B, C);
4045 + return luaK_jump(fs);
4049 +static void fixjump (FuncState *fs, int pc, int dest) {
4050 + Instruction *jmp = &fs->f->code[pc];
4051 + int offset = dest-(pc+1);
4052 + lua_assert(dest != NO_JUMP);
4053 + if (abs(offset) > MAXARG_sBx)
4054 + luaX_syntaxerror(fs->ls, "control structure too long");
4055 + SETARG_sBx(*jmp, offset);
4060 +** returns current `pc' and marks it as a jump target (to avoid wrong
4061 +** optimizations with consecutive instructions not in the same basic block).
4063 +int luaK_getlabel (FuncState *fs) {
4064 + fs->lasttarget = fs->pc;
4069 +static int getjump (FuncState *fs, int pc) {
4070 + int offset = GETARG_sBx(fs->f->code[pc]);
4071 + if (offset == NO_JUMP) /* point to itself represents end of list */
4072 + return NO_JUMP; /* end of list */
4074 + return (pc+1)+offset; /* turn offset into absolute position */
4078 +static Instruction *getjumpcontrol (FuncState *fs, int pc) {
4079 + Instruction *pi = &fs->f->code[pc];
4080 + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
4088 +** check whether list has any jump that do not produce a value
4089 +** (or produce an inverted value)
4091 +static int need_value (FuncState *fs, int list) {
4092 + for (; list != NO_JUMP; list = getjump(fs, list)) {
4093 + Instruction i = *getjumpcontrol(fs, list);
4094 + if (GET_OPCODE(i) != OP_TESTSET) return 1;
4096 + return 0; /* not found */
4100 +static int patchtestreg (FuncState *fs, int node, int reg) {
4101 + Instruction *i = getjumpcontrol(fs, node);
4102 + if (GET_OPCODE(*i) != OP_TESTSET)
4103 + return 0; /* cannot patch other instructions */
4104 + if (reg != NO_REG && reg != GETARG_B(*i))
4105 + SETARG_A(*i, reg);
4106 + else /* no register to put value or register already has the value */
4107 + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
4113 +static void removevalues (FuncState *fs, int list) {
4114 + for (; list != NO_JUMP; list = getjump(fs, list))
4115 + patchtestreg(fs, list, NO_REG);
4119 +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
4121 + while (list != NO_JUMP) {
4122 + int next = getjump(fs, list);
4123 + if (patchtestreg(fs, list, reg))
4124 + fixjump(fs, list, vtarget);
4126 + fixjump(fs, list, dtarget); /* jump to default target */
4132 +static void dischargejpc (FuncState *fs) {
4133 + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
4134 + fs->jpc = NO_JUMP;
4138 +void luaK_patchlist (FuncState *fs, int list, int target) {
4139 + if (target == fs->pc)
4140 + luaK_patchtohere(fs, list);
4142 + lua_assert(target < fs->pc);
4143 + patchlistaux(fs, list, target, NO_REG, target);
4148 +void luaK_patchtohere (FuncState *fs, int list) {
4149 + luaK_getlabel(fs);
4150 + luaK_concat(fs, &fs->jpc, list);
4154 +void luaK_concat (FuncState *fs, int *l1, int l2) {
4155 + if (l2 == NO_JUMP) return;
4156 + else if (*l1 == NO_JUMP)
4161 + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
4163 + fixjump(fs, list, l2);
4168 +void luaK_checkstack (FuncState *fs, int n) {
4169 + int newstack = fs->freereg + n;
4170 + if (newstack > fs->f->maxstacksize) {
4171 + if (newstack >= MAXSTACK)
4172 + luaX_syntaxerror(fs->ls, "function or expression too complex");
4173 + fs->f->maxstacksize = cast_byte(newstack);
4178 +void luaK_reserveregs (FuncState *fs, int n) {
4179 + luaK_checkstack(fs, n);
4184 +static void freereg (FuncState *fs, int reg) {
4185 + if (!ISK(reg) && reg >= fs->nactvar) {
4187 + lua_assert(reg == fs->freereg);
4192 +static void freeexp (FuncState *fs, expdesc *e) {
4193 + if (e->k == VNONRELOC)
4194 + freereg(fs, e->u.s.info);
4198 +static int addk (FuncState *fs, TValue *k, TValue *v) {
4199 + lua_State *L = fs->L;
4200 + TValue *idx = luaH_set(L, fs->h, k);
4202 + int oldsize = f->sizek;
4203 + if (ttisnumber(idx)) {
4204 + lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
4205 + return cast_int(nvalue(idx));
4207 + else { /* constant not found; create a new entry */
4208 + setnvalue(idx, cast_num(fs->nk));
4209 + luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
4210 + MAXARG_Bx, "constant table overflow");
4211 + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
4212 + setobj(L, &f->k[fs->nk], v);
4213 + luaC_barrier(L, f, v);
4219 +int luaK_stringK (FuncState *fs, TString *s) {
4221 + setsvalue(fs->L, &o, s);
4222 + return addk(fs, &o, &o);
4226 +int luaK_numberK (FuncState *fs, lua_Number r) {
4229 + return addk(fs, &o, &o);
4233 +static int boolK (FuncState *fs, int b) {
4236 + return addk(fs, &o, &o);
4240 +static int nilK (FuncState *fs) {
4243 + /* cannot use nil as key; instead use table itself to represent nil */
4244 + sethvalue(fs->L, &k, fs->h);
4245 + return addk(fs, &k, &v);
4249 +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
4250 + if (e->k == VCALL) { /* expression is an open function call? */
4251 + SETARG_C(getcode(fs, e), nresults+1);
4253 + else if (e->k == VVARARG) {
4254 + SETARG_B(getcode(fs, e), nresults+1);
4255 + SETARG_A(getcode(fs, e), fs->freereg);
4256 + luaK_reserveregs(fs, 1);
4261 +void luaK_setoneret (FuncState *fs, expdesc *e) {
4262 + if (e->k == VCALL) { /* expression is an open function call? */
4264 + e->u.s.info = GETARG_A(getcode(fs, e));
4266 + else if (e->k == VVARARG) {
4267 + SETARG_B(getcode(fs, e), 2);
4268 + e->k = VRELOCABLE; /* can relocate its simple result */
4273 +void luaK_dischargevars (FuncState *fs, expdesc *e) {
4280 + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
4281 + e->k = VRELOCABLE;
4285 + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
4286 + e->k = VRELOCABLE;
4290 + freereg(fs, e->u.s.aux);
4291 + freereg(fs, e->u.s.info);
4292 + e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
4293 + e->k = VRELOCABLE;
4298 + luaK_setoneret(fs, e);
4301 + default: break; /* there is one value available (somewhere) */
4306 +static int code_label (FuncState *fs, int A, int b, int jump) {
4307 + luaK_getlabel(fs); /* those instructions may be jump targets */
4308 + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
4312 +static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
4313 + luaK_dischargevars(fs, e);
4316 + luaK_nil(fs, reg, 1);
4319 + case VFALSE: case VTRUE: {
4320 + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
4324 + luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
4328 + luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
4331 + case VRELOCABLE: {
4332 + Instruction *pc = &getcode(fs, e);
4333 + SETARG_A(*pc, reg);
4337 + if (reg != e->u.s.info)
4338 + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
4342 + lua_assert(e->k == VVOID || e->k == VJMP);
4343 + return; /* nothing to do... */
4346 + e->u.s.info = reg;
4351 +static void discharge2anyreg (FuncState *fs, expdesc *e) {
4352 + if (e->k != VNONRELOC) {
4353 + luaK_reserveregs(fs, 1);
4354 + discharge2reg(fs, e, fs->freereg-1);
4359 +static void exp2reg (FuncState *fs, expdesc *e, int reg) {
4360 + discharge2reg(fs, e, reg);
4362 + luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
4363 + if (hasjumps(e)) {
4364 + int final; /* position after whole expression */
4365 + int p_f = NO_JUMP; /* position of an eventual LOAD false */
4366 + int p_t = NO_JUMP; /* position of an eventual LOAD true */
4367 + if (need_value(fs, e->t) || need_value(fs, e->f)) {
4368 + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
4369 + p_f = code_label(fs, reg, 0, 1);
4370 + p_t = code_label(fs, reg, 1, 0);
4371 + luaK_patchtohere(fs, fj);
4373 + final = luaK_getlabel(fs);
4374 + patchlistaux(fs, e->f, final, reg, p_f);
4375 + patchlistaux(fs, e->t, final, reg, p_t);
4377 + e->f = e->t = NO_JUMP;
4378 + e->u.s.info = reg;
4383 +void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
4384 + luaK_dischargevars(fs, e);
4386 + luaK_reserveregs(fs, 1);
4387 + exp2reg(fs, e, fs->freereg - 1);
4391 +int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
4392 + luaK_dischargevars(fs, e);
4393 + if (e->k == VNONRELOC) {
4394 + if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
4395 + if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
4396 + exp2reg(fs, e, e->u.s.info); /* put value on it */
4397 + return e->u.s.info;
4400 + luaK_exp2nextreg(fs, e); /* default */
4401 + return e->u.s.info;
4405 +void luaK_exp2val (FuncState *fs, expdesc *e) {
4407 + luaK_exp2anyreg(fs, e);
4409 + luaK_dischargevars(fs, e);
4413 +int luaK_exp2RK (FuncState *fs, expdesc *e) {
4414 + luaK_exp2val(fs, e);
4420 + if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
4421 + e->u.s.info = (e->k == VNIL) ? nilK(fs) :
4422 + (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
4423 + boolK(fs, (e->k == VTRUE));
4425 + return RKASK(e->u.s.info);
4430 + if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
4431 + return RKASK(e->u.s.info);
4436 + /* not a constant in the right range: put it in a register */
4437 + return luaK_exp2anyreg(fs, e);
4441 +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
4445 + exp2reg(fs, ex, var->u.s.info);
4449 + int e = luaK_exp2anyreg(fs, ex);
4450 + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
4454 + int e = luaK_exp2anyreg(fs, ex);
4455 + luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
4459 + int e = luaK_exp2RK(fs, ex);
4460 + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
4464 + lua_assert(0); /* invalid var kind to store */
4472 +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
4474 + luaK_exp2anyreg(fs, e);
4476 + func = fs->freereg;
4477 + luaK_reserveregs(fs, 2);
4478 + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
4480 + e->u.s.info = func;
4485 +static void invertjump (FuncState *fs, expdesc *e) {
4486 + Instruction *pc = getjumpcontrol(fs, e->u.s.info);
4487 + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
4488 + GET_OPCODE(*pc) != OP_TEST);
4489 + SETARG_A(*pc, !(GETARG_A(*pc)));
4493 +static int jumponcond (FuncState *fs, expdesc *e, int cond) {
4494 + if (e->k == VRELOCABLE) {
4495 + Instruction ie = getcode(fs, e);
4496 + if (GET_OPCODE(ie) == OP_NOT) {
4497 + fs->pc--; /* remove previous OP_NOT */
4498 + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
4500 + /* else go through */
4502 + discharge2anyreg(fs, e);
4504 + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
4508 +void luaK_goiftrue (FuncState *fs, expdesc *e) {
4509 + int pc; /* pc of last jump */
4510 + luaK_dischargevars(fs, e);
4512 + case VK: case VKNUM: case VTRUE: {
4513 + pc = NO_JUMP; /* always true; do nothing */
4517 + pc = luaK_jump(fs); /* always jump */
4521 + invertjump(fs, e);
4526 + pc = jumponcond(fs, e, 0);
4530 + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
4531 + luaK_patchtohere(fs, e->t);
4536 +static void luaK_goiffalse (FuncState *fs, expdesc *e) {
4537 + int pc; /* pc of last jump */
4538 + luaK_dischargevars(fs, e);
4540 + case VNIL: case VFALSE: {
4541 + pc = NO_JUMP; /* always false; do nothing */
4545 + pc = luaK_jump(fs); /* always jump */
4553 + pc = jumponcond(fs, e, 1);
4557 + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
4558 + luaK_patchtohere(fs, e->f);
4563 +static void codenot (FuncState *fs, expdesc *e) {
4564 + luaK_dischargevars(fs, e);
4566 + case VNIL: case VFALSE: {
4570 + case VK: case VKNUM: case VTRUE: {
4575 + invertjump(fs, e);
4580 + discharge2anyreg(fs, e);
4582 + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
4583 + e->k = VRELOCABLE;
4587 + lua_assert(0); /* cannot happen */
4591 + /* interchange true and false lists */
4592 + { int temp = e->f; e->f = e->t; e->t = temp; }
4593 + removevalues(fs, e->f);
4594 + removevalues(fs, e->t);
4598 +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
4599 + t->u.s.aux = luaK_exp2RK(fs, k);
4604 +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
4605 + lua_Number v1, v2, r;
4606 + if (!isnumeral(e1) || !isnumeral(e2)) return 0;
4610 + case OP_ADD: r = luai_numadd(v1, v2); break;
4611 + case OP_SUB: r = luai_numsub(v1, v2); break;
4612 + case OP_MUL: r = luai_nummul(v1, v2); break;
4614 + if (v2 == 0) return 0; /* do not attempt to divide by 0 */
4615 + r = luai_numdiv(v1, v2); break;
4617 + if (v2 == 0) return 0; /* do not attempt to divide by 0 */
4618 + r = luai_nummod(v1, v2); break;
4619 + case OP_POW: r = luai_numpow(v1, v2); break;
4620 + case OP_UNM: r = luai_numunm(v1); break;
4621 + case OP_LEN: return 0; /* no constant folding for 'len' */
4622 + default: lua_assert(0); r = 0; break;
4624 + if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
4630 +static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
4631 + if (constfolding(op, e1, e2))
4634 + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
4635 + int o1 = luaK_exp2RK(fs, e1);
4644 + e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
4645 + e1->k = VRELOCABLE;
4650 +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
4652 + int o1 = luaK_exp2RK(fs, e1);
4653 + int o2 = luaK_exp2RK(fs, e2);
4656 + if (cond == 0 && op != OP_EQ) {
4657 + int temp; /* exchange args to replace by `<' or `<=' */
4658 + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
4661 + e1->u.s.info = condjump(fs, op, cond, o1, o2);
4666 +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
4668 + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
4671 + if (!isnumeral(e))
4672 + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
4673 + codearith(fs, OP_UNM, e, &e2);
4676 + case OPR_NOT: codenot(fs, e); break;
4678 + luaK_exp2anyreg(fs, e); /* cannot operate on constants */
4679 + codearith(fs, OP_LEN, e, &e2);
4682 + default: lua_assert(0);
4687 +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
4690 + luaK_goiftrue(fs, v);
4694 + luaK_goiffalse(fs, v);
4697 + case OPR_CONCAT: {
4698 + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
4701 + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
4702 + case OPR_MOD: case OPR_POW: {
4703 + if (!isnumeral(v)) luaK_exp2RK(fs, v);
4707 + luaK_exp2RK(fs, v);
4714 +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
4717 + lua_assert(e1->t == NO_JUMP); /* list must be closed */
4718 + luaK_dischargevars(fs, e2);
4719 + luaK_concat(fs, &e2->f, e1->f);
4724 + lua_assert(e1->f == NO_JUMP); /* list must be closed */
4725 + luaK_dischargevars(fs, e2);
4726 + luaK_concat(fs, &e2->t, e1->t);
4730 + case OPR_CONCAT: {
4731 + luaK_exp2val(fs, e2);
4732 + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
4733 + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
4735 + SETARG_B(getcode(fs, e2), e1->u.s.info);
4736 + e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
4739 + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
4740 + codearith(fs, OP_CONCAT, e1, e2);
4744 + case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
4745 + case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
4746 + case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
4747 + case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
4748 + case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
4749 + case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
4750 + case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
4751 + case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
4752 + case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
4753 + case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
4754 + case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
4755 + case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
4756 + default: lua_assert(0);
4761 +void luaK_fixline (FuncState *fs, int line) {
4762 + fs->f->lineinfo[fs->pc - 1] = line;
4766 +static int luaK_code (FuncState *fs, Instruction i, int line) {
4768 + dischargejpc(fs); /* `pc' will change */
4769 + /* put new instruction in code array */
4770 + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
4771 + MAX_INT, "code size overflow");
4772 + f->code[fs->pc] = i;
4773 + /* save corresponding line information */
4774 + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
4775 + MAX_INT, "code size overflow");
4776 + f->lineinfo[fs->pc] = line;
4781 +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
4782 + lua_assert(getOpMode(o) == iABC);
4783 + lua_assert(getBMode(o) != OpArgN || b == 0);
4784 + lua_assert(getCMode(o) != OpArgN || c == 0);
4785 + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
4789 +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
4790 + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
4791 + lua_assert(getCMode(o) == OpArgN);
4792 + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
4796 +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
4797 + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
4798 + int b = (tostore == LUA_MULTRET) ? 0 : tostore;
4799 + lua_assert(tostore != 0);
4800 + if (c <= MAXARG_C)
4801 + luaK_codeABC(fs, OP_SETLIST, base, b, c);
4803 + luaK_codeABC(fs, OP_SETLIST, base, b, 0);
4804 + luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
4806 + fs->freereg = base + 1; /* free registers with list values */
4810 +++ b/extensions/LUA/lua/lcode.h
4813 +** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $
4814 +** Code generator for Lua
4815 +** See Copyright Notice in lua.h
4822 +#include "lobject.h"
4823 +#include "lopcodes.h"
4824 +#include "lparser.h"
4828 +** Marks the end of a patch list. It is an invalid value both as an absolute
4829 +** address, and as a list link (would link an element to itself).
4831 +#define NO_JUMP (-1)
4835 +** grep "ORDER OPR" if you change these enums
4837 +typedef enum BinOpr {
4838 + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
4841 + OPR_LT, OPR_LE, OPR_GT, OPR_GE,
4847 +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
4850 +#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
4852 +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
4854 +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
4856 +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
4857 +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
4858 +LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
4859 +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
4860 +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
4861 +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
4862 +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
4863 +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
4864 +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
4865 +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
4866 +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
4867 +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
4868 +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
4869 +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
4870 +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
4871 +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
4872 +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
4873 +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
4874 +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
4875 +LUAI_FUNC int luaK_jump (FuncState *fs);
4876 +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
4877 +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
4878 +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
4879 +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
4880 +LUAI_FUNC int luaK_getlabel (FuncState *fs);
4881 +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
4882 +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
4883 +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
4884 +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
4889 +++ b/extensions/LUA/lua/ldebug.c
4892 +** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $
4894 +** See Copyright Notice in lua.h
4898 +#include <stdarg.h>
4899 +#include <stddef.h>
4900 +#include <string.h>
4909 +#include "ldebug.h"
4912 +#include "lobject.h"
4913 +#include "lopcodes.h"
4914 +#include "lstate.h"
4915 +#include "lstring.h"
4916 +#include "ltable.h"
4922 +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
4925 +static int currentpc (lua_State *L, CallInfo *ci) {
4926 + if (!isLua(ci)) return -1; /* function is not a Lua function? */
4928 + ci->savedpc = L->savedpc;
4929 + return pcRel(ci->savedpc, ci_func(ci)->l.p);
4933 +static int currentline (lua_State *L, CallInfo *ci) {
4934 + int pc = currentpc(L, ci);
4936 + return -1; /* only active lua functions have current-line information */
4938 + return getline(ci_func(ci)->l.p, pc);
4943 +** this function can be called asynchronous (e.g. during a signal)
4945 +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
4946 + if (func == NULL || mask == 0) { /* turn off hooks? */
4951 + L->basehookcount = count;
4952 + resethookcount(L);
4953 + L->hookmask = cast_byte(mask);
4958 +LUA_API lua_Hook lua_gethook (lua_State *L) {
4963 +LUA_API int lua_gethookmask (lua_State *L) {
4964 + return L->hookmask;
4968 +LUA_API int lua_gethookcount (lua_State *L) {
4969 + return L->basehookcount;
4973 +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
4977 + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
4979 + if (f_isLua(ci)) /* Lua function? */
4980 + level -= ci->tailcalls; /* skip lost tail calls */
4982 + if (level == 0 && ci > L->base_ci) { /* level found? */
4984 + ar->i_ci = cast_int(ci - L->base_ci);
4986 + else if (level < 0) { /* level is of a lost tail call? */
4990 + else status = 0; /* no such level */
4996 +static Proto *getluaproto (CallInfo *ci) {
4997 + return (isLua(ci) ? ci_func(ci)->l.p : NULL);
5001 +static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
5003 + Proto *fp = getluaproto(ci);
5004 + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
5005 + return name; /* is a local variable in a Lua function */
5007 + StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
5008 + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
5009 + return "(*temporary)";
5016 +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
5017 + CallInfo *ci = L->base_ci + ar->i_ci;
5018 + const char *name = findlocal(L, ci, n);
5021 + luaA_pushobject(L, ci->base + (n - 1));
5027 +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
5028 + CallInfo *ci = L->base_ci + ar->i_ci;
5029 + const char *name = findlocal(L, ci, n);
5032 + setobjs2s(L, ci->base + (n - 1), L->top - 1);
5033 + L->top--; /* pop value */
5039 +static void funcinfo (lua_Debug *ar, Closure *cl) {
5041 + ar->source = "=[C]";
5042 + ar->linedefined = -1;
5043 + ar->lastlinedefined = -1;
5047 + ar->source = getstr(cl->l.p->source);
5048 + ar->linedefined = cl->l.p->linedefined;
5049 + ar->lastlinedefined = cl->l.p->lastlinedefined;
5050 + ar->what = (ar->linedefined == 0) ? "main" : "Lua";
5052 + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
5056 +static void info_tailcall (lua_Debug *ar) {
5057 + ar->name = ar->namewhat = "";
5058 + ar->what = "tail";
5059 + ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
5060 + ar->source = "=(tail call)";
5061 + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
5066 +static void collectvalidlines (lua_State *L, Closure *f) {
5067 + if (f == NULL || f->c.isC) {
5068 + setnilvalue(L->top);
5071 + Table *t = luaH_new(L, 0, 0);
5072 + int *lineinfo = f->l.p->lineinfo;
5074 + for (i=0; i<f->l.p->sizelineinfo; i++)
5075 + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
5076 + sethvalue(L, L->top, t);
5082 +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
5083 + Closure *f, CallInfo *ci) {
5086 + info_tailcall(ar);
5089 + for (; *what; what++) {
5096 + ar->currentline = (ci) ? currentline(L, ci) : -1;
5100 + ar->nups = f->c.nupvalues;
5104 + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
5105 + if (ar->namewhat == NULL) {
5106 + ar->namewhat = ""; /* not found */
5112 + case 'f': /* handled by lua_getinfo */
5114 + default: status = 0; /* invalid option */
5121 +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
5123 + Closure *f = NULL;
5124 + CallInfo *ci = NULL;
5126 + if (*what == '>') {
5127 + StkId func = L->top - 1;
5128 + luai_apicheck(L, ttisfunction(func));
5129 + what++; /* skip the '>' */
5130 + f = clvalue(func);
5131 + L->top--; /* pop function */
5133 + else if (ar->i_ci != 0) { /* no tail call? */
5134 + ci = L->base_ci + ar->i_ci;
5135 + lua_assert(ttisfunction(ci->func));
5136 + f = clvalue(ci->func);
5138 + status = auxgetinfo(L, what, ar, f, ci);
5139 + if (strchr(what, 'f')) {
5140 + if (f == NULL) setnilvalue(L->top);
5141 + else setclvalue(L, L->top, f);
5144 + if (strchr(what, 'L'))
5145 + collectvalidlines(L, f);
5152 +** {======================================================
5153 +** Symbolic Execution and code checker
5154 +** =======================================================
5157 +#define check(x) if (!(x)) return 0;
5159 +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
5161 +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
5165 +static int precheck (const Proto *pt) {
5166 + check(pt->maxstacksize <= MAXSTACK);
5167 + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
5168 + check(!(pt->is_vararg & VARARG_NEEDSARG) ||
5169 + (pt->is_vararg & VARARG_HASARG));
5170 + check(pt->sizeupvalues <= pt->nups);
5171 + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
5172 + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
5177 +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
5179 +int luaG_checkopenop (Instruction i) {
5180 + switch (GET_OPCODE(i)) {
5184 + case OP_SETLIST: {
5185 + check(GETARG_B(i) == 0);
5188 + default: return 0; /* invalid instruction after an open call */
5193 +static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
5195 + case OpArgN: check(r == 0); break;
5196 + case OpArgU: break;
5197 + case OpArgR: checkreg(pt, r); break;
5199 + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
5206 +static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
5208 + int last; /* stores position of last instruction that changed `reg' */
5209 + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
5210 + check(precheck(pt));
5211 + for (pc = 0; pc < lastpc; pc++) {
5212 + Instruction i = pt->code[pc];
5213 + OpCode op = GET_OPCODE(i);
5214 + int a = GETARG_A(i);
5217 + check(op < NUM_OPCODES);
5219 + switch (getOpMode(op)) {
5223 + check(checkArgMode(pt, b, getBMode(op)));
5224 + check(checkArgMode(pt, c, getCMode(op)));
5229 + if (getBMode(op) == OpArgK) check(b < pt->sizek);
5233 + b = GETARG_sBx(i);
5234 + if (getBMode(op) == OpArgR) {
5235 + int dest = pc+1+b;
5236 + check(0 <= dest && dest < pt->sizecode);
5239 + /* check that it does not jump to a setlist count; this
5240 + is tricky, because the count from a previous setlist may
5241 + have the same value of an invalid setlist; so, we must
5242 + go all the way back to the first of them (if any) */
5243 + for (j = 0; j < dest; j++) {
5244 + Instruction d = pt->code[dest-1-j];
5245 + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
5247 + /* if 'j' is even, previous value is not a setlist (even if
5248 + it looks like one) */
5249 + check((j&1) == 0);
5255 + if (testAMode(op)) {
5256 + if (a == reg) last = pc; /* change register `a' */
5258 + if (testTMode(op)) {
5259 + check(pc+2 < pt->sizecode); /* check skip */
5260 + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
5263 + case OP_LOADBOOL: {
5264 + if (c == 1) { /* does it jump? */
5265 + check(pc+2 < pt->sizecode); /* check its jump */
5266 + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
5267 + GETARG_C(pt->code[pc+1]) != 0);
5271 + case OP_LOADNIL: {
5272 + if (a <= reg && reg <= b)
5273 + last = pc; /* set registers from `a' to `b' */
5277 + case OP_SETUPVAL: {
5278 + check(b < pt->nups);
5281 + case OP_GETGLOBAL:
5282 + case OP_SETGLOBAL: {
5283 + check(ttisstring(&pt->k[b]));
5287 + checkreg(pt, a+1);
5288 + if (reg == a+1) last = pc;
5292 + check(b < c); /* at least two operands */
5295 + case OP_TFORLOOP: {
5296 + check(c >= 1); /* at least one result (control variable) */
5297 + checkreg(pt, a+2+c); /* space for results */
5298 + if (reg >= a+2) last = pc; /* affect all regs above its base */
5303 + checkreg(pt, a+3);
5306 + int dest = pc+1+b;
5307 + /* not full check and jump is forward and do not skip `lastpc'? */
5308 + if (reg != NO_REG && pc < dest && dest <= lastpc)
5309 + pc += b; /* do the jump */
5313 + case OP_TAILCALL: {
5315 + checkreg(pt, a+b-1);
5317 + c--; /* c = num. returns */
5318 + if (c == LUA_MULTRET) {
5319 + check(checkopenop(pt, pc));
5322 + checkreg(pt, a+c-1);
5323 + if (reg >= a) last = pc; /* affect all registers above base */
5327 + b--; /* b = num. returns */
5328 + if (b > 0) checkreg(pt, a+b-1);
5331 + case OP_SETLIST: {
5332 + if (b > 0) checkreg(pt, a + b);
5335 + check(pc < pt->sizecode - 1);
5339 + case OP_CLOSURE: {
5341 + check(b < pt->sizep);
5342 + nup = pt->p[b]->nups;
5343 + check(pc + nup < pt->sizecode);
5344 + for (j = 1; j <= nup; j++) {
5345 + OpCode op1 = GET_OPCODE(pt->code[pc + j]);
5346 + check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
5348 + if (reg != NO_REG) /* tracing? */
5349 + pc += nup; /* do not 'execute' these pseudo-instructions */
5353 + check((pt->is_vararg & VARARG_ISVARARG) &&
5354 + !(pt->is_vararg & VARARG_NEEDSARG));
5356 + if (b == LUA_MULTRET) check(checkopenop(pt, pc));
5357 + checkreg(pt, a+b-1);
5363 + return pt->code[last];
5370 +/* }====================================================== */
5373 +int luaG_checkcode (const Proto *pt) {
5374 + return (symbexec(pt, pt->sizecode, NO_REG) != 0);
5378 +static const char *kname (Proto *p, int c) {
5379 + if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
5380 + return svalue(&p->k[INDEXK(c)]);
5386 +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
5387 + const char **name) {
5388 + if (isLua(ci)) { /* a Lua function? */
5389 + Proto *p = ci_func(ci)->l.p;
5390 + int pc = currentpc(L, ci);
5392 + *name = luaF_getlocalname(p, stackpos+1, pc);
5393 + if (*name) /* is a local? */
5395 + i = symbexec(p, pc, stackpos); /* try symbolic execution */
5396 + lua_assert(pc != -1);
5397 + switch (GET_OPCODE(i)) {
5398 + case OP_GETGLOBAL: {
5399 + int g = GETARG_Bx(i); /* global index */
5400 + lua_assert(ttisstring(&p->k[g]));
5401 + *name = svalue(&p->k[g]);
5405 + int a = GETARG_A(i);
5406 + int b = GETARG_B(i); /* move from `b' to `a' */
5408 + return getobjname(L, ci, b, name); /* get name for `b' */
5411 + case OP_GETTABLE: {
5412 + int k = GETARG_C(i); /* key index */
5413 + *name = kname(p, k);
5416 + case OP_GETUPVAL: {
5417 + int u = GETARG_B(i); /* upvalue index */
5418 + *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
5422 + int k = GETARG_C(i); /* key index */
5423 + *name = kname(p, k);
5429 + return NULL; /* no useful name found */
5433 +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
5435 + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
5436 + return NULL; /* calling function is not Lua (or is unknown) */
5437 + ci--; /* calling function */
5438 + i = ci_func(ci)->l.p->code[currentpc(L, ci)];
5439 + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
5440 + GET_OPCODE(i) == OP_TFORLOOP)
5441 + return getobjname(L, ci, GETARG_A(i), name);
5443 + return NULL; /* no useful name can be found */
5447 +/* only ANSI way to check whether a pointer points to an array */
5448 +static int isinstack (CallInfo *ci, const TValue *o) {
5450 + for (p = ci->base; p < ci->top; p++)
5451 + if (o == p) return 1;
5456 +void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
5457 + const char *name = NULL;
5458 + const char *t = luaT_typenames[ttype(o)];
5459 + const char *kind = (isinstack(L->ci, o)) ?
5460 + getobjname(L, L->ci, cast_int(o - L->base), &name) :
5463 + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
5464 + op, kind, name, t);
5466 + luaG_runerror(L, "attempt to %s a %s value", op, t);
5470 +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
5471 + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
5472 + lua_assert(!ttisstring(p1) && !ttisnumber(p1));
5473 + luaG_typeerror(L, p1, "concatenate");
5477 +void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
5479 + if (luaV_tonumber(p1, &temp) == NULL)
5480 + p2 = p1; /* first operand is wrong */
5481 + luaG_typeerror(L, p2, "perform arithmetic on");
5485 +int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
5486 + const char *t1 = luaT_typenames[ttype(p1)];
5487 + const char *t2 = luaT_typenames[ttype(p2)];
5488 + if (t1[2] == t2[2])
5489 + luaG_runerror(L, "attempt to compare two %s values", t1);
5491 + luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
5496 +static void addinfo (lua_State *L, const char *msg) {
5497 + CallInfo *ci = L->ci;
5498 + if (isLua(ci)) { /* is Lua code? */
5499 + char buff[LUA_IDSIZE]; /* add file:line information */
5500 + int line = currentline(L, ci);
5501 + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
5502 + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
5507 +void luaG_errormsg (lua_State *L) {
5508 + if (L->errfunc != 0) { /* is there an error handling function? */
5509 + StkId errfunc = restorestack(L, L->errfunc);
5510 + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
5511 + setobjs2s(L, L->top, L->top - 1); /* move argument */
5512 + setobjs2s(L, L->top - 1, errfunc); /* push function */
5514 + luaD_call(L, L->top - 2, 1); /* call it */
5516 + luaD_throw(L, LUA_ERRRUN);
5520 +void luaG_runerror (lua_State *L, const char *fmt, ...) {
5522 + va_start(argp, fmt);
5523 + addinfo(L, luaO_pushvfstring(L, fmt, argp));
5529 +++ b/extensions/LUA/lua/ldebug.h
5532 +** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $
5533 +** Auxiliary functions from Debug Interface module
5534 +** See Copyright Notice in lua.h
5541 +#include "lstate.h"
5544 +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
5546 +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
5548 +#define resethookcount(L) (L->hookcount = L->basehookcount)
5551 +LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
5552 + const char *opname);
5553 +LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
5554 +LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
5555 + const TValue *p2);
5556 +LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
5557 + const TValue *p2);
5558 +LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
5559 +LUAI_FUNC void luaG_errormsg (lua_State *L);
5560 +LUAI_FUNC int luaG_checkcode (const Proto *pt);
5561 +LUAI_FUNC int luaG_checkopenop (Instruction i);
5565 +++ b/extensions/LUA/lua/ldo.c
5568 +** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
5569 +** Stack and Call structure of Lua
5570 +** See Copyright Notice in lua.h
5573 +#include <setjmp.h>
5574 +#include <stdlib.h>
5575 +#include <string.h>
5582 +#include "ldebug.h"
5587 +#include "lobject.h"
5588 +#include "lopcodes.h"
5589 +#include "lparser.h"
5590 +#include "lstate.h"
5591 +#include "lstring.h"
5592 +#include "ltable.h"
5594 +#include "lundump.h"
5601 +** {======================================================
5602 +** Error-recovery functions
5603 +** =======================================================
5607 +/* chain list of long jump buffers */
5608 +struct lua_longjmp {
5609 + struct lua_longjmp *previous;
5611 + volatile int status; /* error code */
5615 +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
5616 + switch (errcode) {
5617 + case LUA_ERRMEM: {
5618 + setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
5621 + case LUA_ERRERR: {
5622 + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
5625 + case LUA_ERRSYNTAX:
5626 + case LUA_ERRRUN: {
5627 + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
5631 + L->top = oldtop + 1;
5635 +static void restore_stack_limit (lua_State *L) {
5636 + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
5637 + if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
5638 + int inuse = cast_int(L->ci - L->base_ci);
5639 + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
5640 + luaD_reallocCI(L, LUAI_MAXCALLS);
5645 +static void resetstack (lua_State *L, int status) {
5646 + L->ci = L->base_ci;
5647 + L->base = L->ci->base;
5648 + luaF_close(L, L->base); /* close eventual pending closures */
5649 + luaD_seterrorobj(L, status, L->base);
5650 + L->nCcalls = L->baseCcalls;
5652 + restore_stack_limit(L);
5654 + L->errorJmp = NULL;
5658 +void luaD_throw (lua_State *L, int errcode) {
5659 + if (L->errorJmp) {
5660 + L->errorJmp->status = errcode;
5661 + LUAI_THROW(L, L->errorJmp);
5664 + L->status = cast_byte(errcode);
5665 + if (G(L)->panic) {
5666 + resetstack(L, errcode);
5670 + exit(EXIT_FAILURE);
5675 +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
5676 + struct lua_longjmp lj;
5678 + lj.previous = L->errorJmp; /* chain new error handler */
5679 + L->errorJmp = &lj;
5683 + L->errorJmp = lj.previous; /* restore old error handler */
5687 +/* }====================================================== */
5690 +static void correctstack (lua_State *L, TValue *oldstack) {
5693 + L->top = (L->top - oldstack) + L->stack;
5694 + for (up = L->openupval; up != NULL; up = up->gch.next)
5695 + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
5696 + for (ci = L->base_ci; ci <= L->ci; ci++) {
5697 + ci->top = (ci->top - oldstack) + L->stack;
5698 + ci->base = (ci->base - oldstack) + L->stack;
5699 + ci->func = (ci->func - oldstack) + L->stack;
5701 + L->base = (L->base - oldstack) + L->stack;
5705 +void luaD_reallocstack (lua_State *L, int newsize) {
5706 + TValue *oldstack = L->stack;
5707 + int realsize = newsize + 1 + EXTRA_STACK;
5708 + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
5709 + luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
5710 + L->stacksize = realsize;
5711 + L->stack_last = L->stack+newsize;
5712 + correctstack(L, oldstack);
5716 +void luaD_reallocCI (lua_State *L, int newsize) {
5717 + CallInfo *oldci = L->base_ci;
5718 + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
5719 + L->size_ci = newsize;
5720 + L->ci = (L->ci - oldci) + L->base_ci;
5721 + L->end_ci = L->base_ci + L->size_ci - 1;
5725 +void luaD_growstack (lua_State *L, int n) {
5726 + if (n <= L->stacksize) /* double size is enough? */
5727 + luaD_reallocstack(L, 2*L->stacksize);
5729 + luaD_reallocstack(L, L->stacksize + n);
5733 +static CallInfo *growCI (lua_State *L) {
5734 + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
5735 + luaD_throw(L, LUA_ERRERR);
5737 + luaD_reallocCI(L, 2*L->size_ci);
5738 + if (L->size_ci > LUAI_MAXCALLS)
5739 + luaG_runerror(L, "stack overflow");
5745 +void luaD_callhook (lua_State *L, int event, int line) {
5746 + lua_Hook hook = L->hook;
5747 + if (hook && L->allowhook) {
5748 + ptrdiff_t top = savestack(L, L->top);
5749 + ptrdiff_t ci_top = savestack(L, L->ci->top);
5752 + ar.currentline = line;
5753 + if (event == LUA_HOOKTAILRET)
5754 + ar.i_ci = 0; /* tail call; no debug information about it */
5756 + ar.i_ci = cast_int(L->ci - L->base_ci);
5757 + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
5758 + L->ci->top = L->top + LUA_MINSTACK;
5759 + lua_assert(L->ci->top <= L->stack_last);
5760 + L->allowhook = 0; /* cannot call hooks inside a hook */
5764 + lua_assert(!L->allowhook);
5766 + L->ci->top = restorestack(L, ci_top);
5767 + L->top = restorestack(L, top);
5772 +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
5774 + int nfixargs = p->numparams;
5775 + Table *htab = NULL;
5776 + StkId base, fixed;
5777 + for (; actual < nfixargs; ++actual)
5778 + setnilvalue(L->top++);
5779 +#if defined(LUA_COMPAT_VARARG)
5780 + if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
5781 + int nvar = actual - nfixargs; /* number of extra arguments */
5782 + lua_assert(p->is_vararg & VARARG_HASARG);
5784 + htab = luaH_new(L, nvar, 1); /* create `arg' table */
5785 + for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
5786 + setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
5787 + /* store counter in field `n' */
5788 + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
5791 + /* move fixed parameters to final position */
5792 + fixed = L->top - actual; /* first fixed argument */
5793 + base = L->top; /* final position of first argument */
5794 + for (i=0; i<nfixargs; i++) {
5795 + setobjs2s(L, L->top++, fixed+i);
5796 + setnilvalue(fixed+i);
5798 + /* add `arg' parameter */
5800 + sethvalue(L, L->top++, htab);
5801 + lua_assert(iswhite(obj2gco(htab)));
5807 +static StkId tryfuncTM (lua_State *L, StkId func) {
5808 + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
5810 + ptrdiff_t funcr = savestack(L, func);
5811 + if (!ttisfunction(tm))
5812 + luaG_typeerror(L, func, "call");
5813 + /* Open a hole inside the stack at `func' */
5814 + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
5816 + func = restorestack(L, funcr); /* previous call may change stack */
5817 + setobj2s(L, func, tm); /* tag method is the new function to be called */
5823 +#define inc_ci(L) \
5824 + ((L->ci == L->end_ci) ? growCI(L) : \
5825 + (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
5828 +int luaD_precall (lua_State *L, StkId func, int nresults) {
5831 + if (!ttisfunction(func)) /* `func' is not a function? */
5832 + func = tryfuncTM(L, func); /* check the `function' tag method */
5833 + funcr = savestack(L, func);
5834 + cl = &clvalue(func)->l;
5835 + L->ci->savedpc = L->savedpc;
5836 + if (!cl->isC) { /* Lua function? prepare its call */
5840 + luaD_checkstack(L, p->maxstacksize);
5841 + func = restorestack(L, funcr);
5842 + if (!p->is_vararg) { /* no varargs? */
5844 + if (L->top > base + p->numparams)
5845 + L->top = base + p->numparams;
5847 + else { /* vararg function */
5848 + int nargs = cast_int(L->top - func) - 1;
5849 + base = adjust_varargs(L, p, nargs);
5850 + func = restorestack(L, funcr); /* previous call may change the stack */
5852 + ci = inc_ci(L); /* now `enter' new function */
5854 + L->base = ci->base = base;
5855 + ci->top = L->base + p->maxstacksize;
5856 + lua_assert(ci->top <= L->stack_last);
5857 + L->savedpc = p->code; /* starting point */
5858 + ci->tailcalls = 0;
5859 + ci->nresults = nresults;
5860 + for (st = L->top; st < ci->top; st++)
5863 + if (L->hookmask & LUA_MASKCALL) {
5864 + L->savedpc++; /* hooks assume 'pc' is already incremented */
5865 + luaD_callhook(L, LUA_HOOKCALL, -1);
5866 + L->savedpc--; /* correct 'pc' */
5870 + else { /* if is a C function, call it */
5873 + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
5874 + ci = inc_ci(L); /* now `enter' new function */
5875 + ci->func = restorestack(L, funcr);
5876 + L->base = ci->base = ci->func + 1;
5877 + ci->top = L->top + LUA_MINSTACK;
5878 + lua_assert(ci->top <= L->stack_last);
5879 + ci->nresults = nresults;
5880 + if (L->hookmask & LUA_MASKCALL)
5881 + luaD_callhook(L, LUA_HOOKCALL, -1);
5883 + n = (*curr_func(L)->c.f)(L); /* do the actual call */
5885 + if (n < 0) /* yielding? */
5888 + luaD_poscall(L, L->top - n);
5895 +static StkId callrethooks (lua_State *L, StkId firstResult) {
5896 + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
5897 + luaD_callhook(L, LUA_HOOKRET, -1);
5898 + if (f_isLua(L->ci)) { /* Lua function? */
5899 + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
5900 + luaD_callhook(L, LUA_HOOKTAILRET, -1);
5902 + return restorestack(L, fr);
5906 +int luaD_poscall (lua_State *L, StkId firstResult) {
5910 + if (L->hookmask & LUA_MASKRET)
5911 + firstResult = callrethooks(L, firstResult);
5913 + res = ci->func; /* res == final position of 1st result */
5914 + wanted = ci->nresults;
5915 + L->base = (ci - 1)->base; /* restore base */
5916 + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
5917 + /* move results to correct place */
5918 + for (i = wanted; i != 0 && firstResult < L->top; i--)
5919 + setobjs2s(L, res++, firstResult++);
5921 + setnilvalue(res++);
5923 + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
5928 +** Call a function (C or Lua). The function to be called is at *func.
5929 +** The arguments are on the stack, right after the function.
5930 +** When returns, all the results are on the stack, starting at the original
5931 +** function position.
5933 +void luaD_call (lua_State *L, StkId func, int nResults) {
5934 + if (++L->nCcalls >= LUAI_MAXCCALLS) {
5935 + if (L->nCcalls == LUAI_MAXCCALLS)
5936 + luaG_runerror(L, "C stack overflow");
5937 + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
5938 + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
5940 + if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
5941 + luaV_execute(L, 1); /* call it */
5947 +static void resume (lua_State *L, void *ud) {
5948 + StkId firstArg = cast(StkId, ud);
5949 + CallInfo *ci = L->ci;
5950 + if (L->status == 0) { /* start coroutine? */
5951 + lua_assert(ci == L->base_ci && firstArg > L->base);
5952 + if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
5955 + else { /* resuming from previous yield */
5956 + lua_assert(L->status == LUA_YIELD);
5958 + if (!f_isLua(ci)) { /* `common' yield? */
5959 + /* finish interrupted execution of `OP_CALL' */
5960 + lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
5961 + GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
5962 + if (luaD_poscall(L, firstArg)) /* complete it... */
5963 + L->top = L->ci->top; /* and correct top if not multiple results */
5965 + else /* yielded inside a hook: just continue its execution */
5966 + L->base = L->ci->base;
5968 + luaV_execute(L, cast_int(L->ci - L->base_ci));
5972 +static int resume_error (lua_State *L, const char *msg) {
5973 + L->top = L->ci->base;
5974 + setsvalue2s(L, L->top, luaS_new(L, msg));
5977 + return LUA_ERRRUN;
5981 +LUA_API int lua_resume (lua_State *L, int nargs) {
5984 + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
5985 + return resume_error(L, "cannot resume non-suspended coroutine");
5986 + if (L->nCcalls >= LUAI_MAXCCALLS)
5987 + return resume_error(L, "C stack overflow");
5988 + luai_userstateresume(L, nargs);
5989 + lua_assert(L->errfunc == 0);
5990 + L->baseCcalls = ++L->nCcalls;
5991 + status = luaD_rawrunprotected(L, resume, L->top - nargs);
5992 + if (status != 0) { /* error? */
5993 + L->status = cast_byte(status); /* mark thread as `dead' */
5994 + luaD_seterrorobj(L, status, L->top);
5995 + L->ci->top = L->top;
5998 + lua_assert(L->nCcalls == L->baseCcalls);
5999 + status = L->status;
6007 +LUA_API int lua_yield (lua_State *L, int nresults) {
6008 + luai_userstateyield(L, nresults);
6010 + if (L->nCcalls > L->baseCcalls)
6011 + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
6012 + L->base = L->top - nresults; /* protect stack slots below */
6013 + L->status = LUA_YIELD;
6019 +int luaD_pcall (lua_State *L, Pfunc func, void *u,
6020 + ptrdiff_t old_top, ptrdiff_t ef) {
6022 + unsigned short oldnCcalls = L->nCcalls;
6023 + ptrdiff_t old_ci = saveci(L, L->ci);
6024 + lu_byte old_allowhooks = L->allowhook;
6025 + ptrdiff_t old_errfunc = L->errfunc;
6027 + status = luaD_rawrunprotected(L, func, u);
6028 + if (status != 0) { /* an error occurred? */
6029 + StkId oldtop = restorestack(L, old_top);
6030 + luaF_close(L, oldtop); /* close eventual pending closures */
6031 + luaD_seterrorobj(L, status, oldtop);
6032 + L->nCcalls = oldnCcalls;
6033 + L->ci = restoreci(L, old_ci);
6034 + L->base = L->ci->base;
6035 + L->savedpc = L->ci->savedpc;
6036 + L->allowhook = old_allowhooks;
6037 + restore_stack_limit(L);
6039 + L->errfunc = old_errfunc;
6046 +** Execute a protected parser.
6048 +struct SParser { /* data to `f_parser' */
6050 + Mbuffer buff; /* buffer to be used by the scanner */
6054 +static void f_parser (lua_State *L, void *ud) {
6058 + struct SParser *p = cast(struct SParser *, ud);
6059 + int c = luaZ_lookahead(p->z);
6061 + tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
6062 + &p->buff, p->name);
6063 + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
6065 + for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
6066 + cl->l.upvals[i] = luaF_newupval(L);
6067 + setclvalue(L, L->top, cl);
6072 +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
6075 + p.z = z; p.name = name;
6076 + luaZ_initbuffer(L, &p.buff);
6077 + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
6078 + luaZ_freebuffer(L, &p.buff);
6083 +++ b/extensions/LUA/lua/ldo.h
6086 +** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $
6087 +** Stack and Call structure of Lua
6088 +** See Copyright Notice in lua.h
6095 +#include "lobject.h"
6096 +#include "lstate.h"
6100 +#define luaD_checkstack(L,n) \
6101 + if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
6102 + luaD_growstack(L, n); \
6103 + else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
6106 +#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
6108 +#define savestack(L,p) ((char *)(p) - (char *)L->stack)
6109 +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
6111 +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
6112 +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
6115 +/* results from luaD_precall */
6116 +#define PCRLUA 0 /* initiated a call to a Lua function */
6117 +#define PCRC 1 /* did a call to a C function */
6118 +#define PCRYIELD 2 /* C funtion yielded */
6121 +/* type of protected functions, to be ran by `runprotected' */
6122 +typedef void (*Pfunc) (lua_State *L, void *ud);
6124 +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
6125 +LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
6126 +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
6127 +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
6128 +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
6129 + ptrdiff_t oldtop, ptrdiff_t ef);
6130 +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
6131 +LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
6132 +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
6133 +LUAI_FUNC void luaD_growstack (lua_State *L, int n);
6135 +LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
6136 +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
6138 +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
6143 +++ b/extensions/LUA/lua/ldump.c
6146 +** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
6147 +** save precompiled Lua chunks
6148 +** See Copyright Notice in lua.h
6151 +#include <stddef.h>
6158 +#include "lobject.h"
6159 +#include "lstate.h"
6160 +#include "lundump.h"
6164 + lua_Writer writer;
6170 +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
6171 +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
6173 +static void DumpBlock(const void* b, size_t size, DumpState* D)
6178 + D->status=(*D->writer)(D->L,b,size,D->data);
6183 +static void DumpChar(int y, DumpState* D)
6189 +static void DumpInt(int x, DumpState* D)
6194 +static void DumpNumber(lua_Number x, DumpState* D)
6199 +static void DumpVector(const void* b, int n, size_t size, DumpState* D)
6202 + DumpMem(b,n,size,D);
6205 +static void DumpString(const TString* s, DumpState* D)
6207 + if (s==NULL || getstr(s)==NULL)
6214 + size_t size=s->tsv.len+1; /* include trailing '\0' */
6216 + DumpBlock(getstr(s),size,D);
6220 +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
6222 +static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
6224 +static void DumpConstants(const Proto* f, DumpState* D)
6228 + for (i=0; i<n; i++)
6230 + const TValue* o=&f->k[i];
6231 + DumpChar(ttype(o),D);
6236 + case LUA_TBOOLEAN:
6237 + DumpChar(bvalue(o),D);
6240 + DumpNumber(nvalue(o),D);
6243 + DumpString(rawtsvalue(o),D);
6246 + lua_assert(0); /* cannot happen */
6252 + for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
6255 +static void DumpDebug(const Proto* f, DumpState* D)
6258 + n= (D->strip) ? 0 : f->sizelineinfo;
6259 + DumpVector(f->lineinfo,n,sizeof(int),D);
6260 + n= (D->strip) ? 0 : f->sizelocvars;
6262 + for (i=0; i<n; i++)
6264 + DumpString(f->locvars[i].varname,D);
6265 + DumpInt(f->locvars[i].startpc,D);
6266 + DumpInt(f->locvars[i].endpc,D);
6268 + n= (D->strip) ? 0 : f->sizeupvalues;
6270 + for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
6273 +static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
6275 + DumpString((f->source==p || D->strip) ? NULL : f->source,D);
6276 + DumpInt(f->linedefined,D);
6277 + DumpInt(f->lastlinedefined,D);
6278 + DumpChar(f->nups,D);
6279 + DumpChar(f->numparams,D);
6280 + DumpChar(f->is_vararg,D);
6281 + DumpChar(f->maxstacksize,D);
6283 + DumpConstants(f,D);
6287 +static void DumpHeader(DumpState* D)
6289 + char h[LUAC_HEADERSIZE];
6291 + DumpBlock(h,LUAC_HEADERSIZE,D);
6295 +** dump Lua function as precompiled chunk
6297 +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
6306 + DumpFunction(f,NULL,&D);
6310 +++ b/extensions/LUA/lua/lfunc.c
6313 +** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $
6314 +** Auxiliary functions to manipulate prototypes and closures
6315 +** See Copyright Notice in lua.h
6319 +#include <stddef.h>
6329 +#include "lobject.h"
6330 +#include "lstate.h"
6334 +Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
6335 + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
6336 + luaC_link(L, obj2gco(c), LUA_TFUNCTION);
6339 + c->c.nupvalues = cast_byte(nelems);
6344 +Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
6345 + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
6346 + luaC_link(L, obj2gco(c), LUA_TFUNCTION);
6349 + c->l.nupvalues = cast_byte(nelems);
6350 + while (nelems--) c->l.upvals[nelems] = NULL;
6355 +UpVal *luaF_newupval (lua_State *L) {
6356 + UpVal *uv = luaM_new(L, UpVal);
6357 + luaC_link(L, obj2gco(uv), LUA_TUPVAL);
6358 + uv->v = &uv->u.value;
6359 + setnilvalue(uv->v);
6364 +UpVal *luaF_findupval (lua_State *L, StkId level) {
6365 + global_State *g = G(L);
6366 + GCObject **pp = &L->openupval;
6369 + while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) {
6370 + lua_assert(p->v != &p->u.value);
6371 + if (p->v == level) { /* found a corresponding upvalue? */
6372 + if (isdead(g, obj2gco(p))) /* is it dead? */
6373 + changewhite(obj2gco(p)); /* ressurect it */
6378 + uv = luaM_new(L, UpVal); /* not found: create a new one */
6379 + uv->tt = LUA_TUPVAL;
6380 + uv->marked = luaC_white(g);
6381 + uv->v = level; /* current value lives in the stack */
6382 + uv->next = *pp; /* chain it in the proper position */
6383 + *pp = obj2gco(uv);
6384 + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
6385 + uv->u.l.next = g->uvhead.u.l.next;
6386 + uv->u.l.next->u.l.prev = uv;
6387 + g->uvhead.u.l.next = uv;
6388 + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
6393 +static void unlinkupval (UpVal *uv) {
6394 + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
6395 + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
6396 + uv->u.l.prev->u.l.next = uv->u.l.next;
6400 +void luaF_freeupval (lua_State *L, UpVal *uv) {
6401 + if (uv->v != &uv->u.value) /* is it open? */
6402 + unlinkupval(uv); /* remove from open list */
6403 + luaM_free(L, uv); /* free upvalue */
6407 +void luaF_close (lua_State *L, StkId level) {
6409 + global_State *g = G(L);
6410 + while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) {
6411 + GCObject *o = obj2gco(uv);
6412 + lua_assert(!isblack(o) && uv->v != &uv->u.value);
6413 + L->openupval = uv->next; /* remove from `open' list */
6415 + luaF_freeupval(L, uv); /* free upvalue */
6418 + setobj(L, &uv->u.value, uv->v);
6419 + uv->v = &uv->u.value; /* now current value lives here */
6420 + luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
6426 +Proto *luaF_newproto (lua_State *L) {
6427 + Proto *f = luaM_new(L, Proto);
6428 + luaC_link(L, obj2gco(f), LUA_TPROTO);
6435 + f->sizelineinfo = 0;
6436 + f->sizeupvalues = 0;
6438 + f->upvalues = NULL;
6441 + f->maxstacksize = 0;
6442 + f->lineinfo = NULL;
6443 + f->sizelocvars = 0;
6444 + f->locvars = NULL;
6445 + f->linedefined = 0;
6446 + f->lastlinedefined = 0;
6452 +void luaF_freeproto (lua_State *L, Proto *f) {
6453 + luaM_freearray(L, f->code, f->sizecode, Instruction);
6454 + luaM_freearray(L, f->p, f->sizep, Proto *);
6455 + luaM_freearray(L, f->k, f->sizek, TValue);
6456 + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
6457 + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
6458 + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
6463 +void luaF_freeclosure (lua_State *L, Closure *c) {
6464 + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
6465 + sizeLclosure(c->l.nupvalues);
6466 + luaM_freemem(L, c, size);
6471 +** Look for n-th local variable at line `line' in function `func'.
6472 +** Returns NULL if not found.
6474 +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
6476 + for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
6477 + if (pc < f->locvars[i].endpc) { /* is variable active? */
6479 + if (local_number == 0)
6480 + return getstr(f->locvars[i].varname);
6483 + return NULL; /* not found */
6487 +++ b/extensions/LUA/lua/lfunc.h
6490 +** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $
6491 +** Auxiliary functions to manipulate prototypes and closures
6492 +** See Copyright Notice in lua.h
6499 +#include "lobject.h"
6502 +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
6503 + cast(int, sizeof(TValue)*((n)-1)))
6505 +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
6506 + cast(int, sizeof(TValue *)*((n)-1)))
6509 +LUAI_FUNC Proto *luaF_newproto (lua_State *L);
6510 +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
6511 +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
6512 +LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
6513 +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
6514 +LUAI_FUNC void luaF_close (lua_State *L, StkId level);
6515 +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
6516 +LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
6517 +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
6518 +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
6524 +++ b/extensions/LUA/lua/lgc.c
6527 +** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $
6528 +** Garbage Collector
6529 +** See Copyright Notice in lua.h
6532 +#include <string.h>
6539 +#include "ldebug.h"
6544 +#include "lobject.h"
6545 +#include "lstate.h"
6546 +#include "lstring.h"
6547 +#include "ltable.h"
6551 +#define GCSTEPSIZE 1024u
6552 +#define GCSWEEPMAX 40
6553 +#define GCSWEEPCOST 10
6554 +#define GCFINALIZECOST 100
6557 +#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
6559 +#define makewhite(g,x) \
6560 + ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g)))
6562 +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
6563 +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
6565 +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
6568 +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
6569 +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
6572 +#define KEYWEAK bitmask(KEYWEAKBIT)
6573 +#define VALUEWEAK bitmask(VALUEWEAKBIT)
6577 +#define markvalue(g,o) { checkconsistency(o); \
6578 + if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
6580 +#define markobject(g,t) { if (iswhite(obj2gco(t))) \
6581 + reallymarkobject(g, obj2gco(t)); }
6584 +#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
6587 +static void removeentry (Node *n) {
6588 + lua_assert(ttisnil(gval(n)));
6589 + if (iscollectable(gkey(n)))
6590 + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
6594 +static void reallymarkobject (global_State *g, GCObject *o) {
6595 + lua_assert(iswhite(o) && !isdead(g, o));
6597 + switch (o->gch.tt) {
6598 + case LUA_TSTRING: {
6601 + case LUA_TUSERDATA: {
6602 + Table *mt = gco2u(o)->metatable;
6603 + gray2black(o); /* udata are never gray */
6604 + if (mt) markobject(g, mt);
6605 + markobject(g, gco2u(o)->env);
6608 + case LUA_TUPVAL: {
6609 + UpVal *uv = gco2uv(o);
6610 + markvalue(g, uv->v);
6611 + if (uv->v == &uv->u.value) /* closed? */
6612 + gray2black(o); /* open upvalues are never black */
6615 + case LUA_TFUNCTION: {
6616 + gco2cl(o)->c.gclist = g->gray;
6620 + case LUA_TTABLE: {
6621 + gco2h(o)->gclist = g->gray;
6625 + case LUA_TTHREAD: {
6626 + gco2th(o)->gclist = g->gray;
6630 + case LUA_TPROTO: {
6631 + gco2p(o)->gclist = g->gray;
6635 + default: lua_assert(0);
6640 +static void marktmu (global_State *g) {
6641 + GCObject *u = g->tmudata;
6645 + makewhite(g, u); /* may be marked, if left from previous GC */
6646 + reallymarkobject(g, u);
6647 + } while (u != g->tmudata);
6652 +/* move `dead' udata that need finalization to list `tmudata' */
6653 +size_t luaC_separateudata (lua_State *L, int all) {
6654 + global_State *g = G(L);
6655 + size_t deadmem = 0;
6656 + GCObject **p = &g->mainthread->next;
6658 + while ((curr = *p) != NULL) {
6659 + if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
6660 + p = &curr->gch.next; /* don't bother with them */
6661 + else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
6662 + markfinalized(gco2u(curr)); /* don't need finalization */
6663 + p = &curr->gch.next;
6665 + else { /* must call its gc method */
6666 + deadmem += sizeudata(gco2u(curr));
6667 + markfinalized(gco2u(curr));
6668 + *p = curr->gch.next;
6669 + /* link `curr' at the end of `tmudata' list */
6670 + if (g->tmudata == NULL) /* list is empty? */
6671 + g->tmudata = curr->gch.next = curr; /* creates a circular list */
6673 + curr->gch.next = g->tmudata->gch.next;
6674 + g->tmudata->gch.next = curr;
6675 + g->tmudata = curr;
6683 +static int traversetable (global_State *g, Table *h) {
6686 + int weakvalue = 0;
6687 + const TValue *mode;
6689 + markobject(g, h->metatable);
6690 + mode = gfasttm(g, h->metatable, TM_MODE);
6691 + if (mode && ttisstring(mode)) { /* is there a weak mode? */
6692 + weakkey = (strchr(svalue(mode), 'k') != NULL);
6693 + weakvalue = (strchr(svalue(mode), 'v') != NULL);
6694 + if (weakkey || weakvalue) { /* is really weak? */
6695 + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
6696 + h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
6697 + (weakvalue << VALUEWEAKBIT));
6698 + h->gclist = g->weak; /* must be cleared after GC, ... */
6699 + g->weak = obj2gco(h); /* ... so put in the appropriate list */
6702 + if (weakkey && weakvalue) return 1;
6706 + markvalue(g, &h->array[i]);
6710 + Node *n = gnode(h, i);
6711 + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
6712 + if (ttisnil(gval(n)))
6713 + removeentry(n); /* remove empty entries */
6715 + lua_assert(!ttisnil(gkey(n)));
6716 + if (!weakkey) markvalue(g, gkey(n));
6717 + if (!weakvalue) markvalue(g, gval(n));
6720 + return weakkey || weakvalue;
6725 +** All marks are conditional because a GC may happen while the
6726 +** prototype is still being created
6728 +static void traverseproto (global_State *g, Proto *f) {
6730 + if (f->source) stringmark(f->source);
6731 + for (i=0; i<f->sizek; i++) /* mark literals */
6732 + markvalue(g, &f->k[i]);
6733 + for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
6734 + if (f->upvalues[i])
6735 + stringmark(f->upvalues[i]);
6737 + for (i=0; i<f->sizep; i++) { /* mark nested protos */
6739 + markobject(g, f->p[i]);
6741 + for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
6742 + if (f->locvars[i].varname)
6743 + stringmark(f->locvars[i].varname);
6749 +static void traverseclosure (global_State *g, Closure *cl) {
6750 + markobject(g, cl->c.env);
6753 + for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
6754 + markvalue(g, &cl->c.upvalue[i]);
6758 + lua_assert(cl->l.nupvalues == cl->l.p->nups);
6759 + markobject(g, cl->l.p);
6760 + for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
6761 + markobject(g, cl->l.upvals[i]);
6766 +static void checkstacksizes (lua_State *L, StkId max) {
6767 + int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */
6768 + int s_used = cast_int(max - L->stack); /* part of stack in use */
6769 + if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
6770 + return; /* do not touch the stacks */
6771 + if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
6772 + luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
6773 + condhardstacktests(luaD_reallocCI(L, ci_used + 1));
6774 + if (4*s_used < L->stacksize &&
6775 + 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
6776 + luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
6777 + condhardstacktests(luaD_reallocstack(L, s_used));
6781 +static void traversestack (global_State *g, lua_State *l) {
6784 + markvalue(g, gt(l));
6786 + for (ci = l->base_ci; ci <= l->ci; ci++) {
6787 + lua_assert(ci->top <= l->stack_last);
6788 + if (lim < ci->top) lim = ci->top;
6790 + for (o = l->stack; o < l->top; o++)
6792 + for (; o <= lim; o++)
6794 + checkstacksizes(l, lim);
6799 +** traverse one gray object, turning it to black.
6800 +** Returns `quantity' traversed.
6802 +static l_mem propagatemark (global_State *g) {
6803 + GCObject *o = g->gray;
6804 + lua_assert(isgray(o));
6806 + switch (o->gch.tt) {
6807 + case LUA_TTABLE: {
6808 + Table *h = gco2h(o);
6809 + g->gray = h->gclist;
6810 + if (traversetable(g, h)) /* table is weak? */
6811 + black2gray(o); /* keep it gray */
6812 + return sizeof(Table) + sizeof(TValue) * h->sizearray +
6813 + sizeof(Node) * sizenode(h);
6815 + case LUA_TFUNCTION: {
6816 + Closure *cl = gco2cl(o);
6817 + g->gray = cl->c.gclist;
6818 + traverseclosure(g, cl);
6819 + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
6820 + sizeLclosure(cl->l.nupvalues);
6822 + case LUA_TTHREAD: {
6823 + lua_State *th = gco2th(o);
6824 + g->gray = th->gclist;
6825 + th->gclist = g->grayagain;
6828 + traversestack(g, th);
6829 + return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
6830 + sizeof(CallInfo) * th->size_ci;
6832 + case LUA_TPROTO: {
6833 + Proto *p = gco2p(o);
6834 + g->gray = p->gclist;
6835 + traverseproto(g, p);
6836 + return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
6837 + sizeof(Proto *) * p->sizep +
6838 + sizeof(TValue) * p->sizek +
6839 + sizeof(int) * p->sizelineinfo +
6840 + sizeof(LocVar) * p->sizelocvars +
6841 + sizeof(TString *) * p->sizeupvalues;
6843 + default: lua_assert(0); return 0;
6848 +static size_t propagateall (global_State *g) {
6850 + while (g->gray) m += propagatemark(g);
6856 +** The next function tells whether a key or value can be cleared from
6857 +** a weak table. Non-collectable objects are never removed from weak
6858 +** tables. Strings behave as `values', so are never removed too. for
6859 +** other objects: if really collected, cannot keep them; for userdata
6860 +** being finalized, keep them in keys, but not in values
6862 +static int iscleared (const TValue *o, int iskey) {
6863 + if (!iscollectable(o)) return 0;
6864 + if (ttisstring(o)) {
6865 + stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
6868 + return iswhite(gcvalue(o)) ||
6869 + (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
6874 +** clear collected entries from weaktables
6876 +static void cleartable (GCObject *l) {
6878 + Table *h = gco2h(l);
6879 + int i = h->sizearray;
6880 + lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
6881 + testbit(h->marked, KEYWEAKBIT));
6882 + if (testbit(h->marked, VALUEWEAKBIT)) {
6884 + TValue *o = &h->array[i];
6885 + if (iscleared(o, 0)) /* value was collected? */
6886 + setnilvalue(o); /* remove value */
6891 + Node *n = gnode(h, i);
6892 + if (!ttisnil(gval(n)) && /* non-empty entry? */
6893 + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
6894 + setnilvalue(gval(n)); /* remove value ... */
6895 + removeentry(n); /* remove entry from table */
6903 +static void freeobj (lua_State *L, GCObject *o) {
6904 + switch (o->gch.tt) {
6905 + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
6906 + case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
6907 + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
6908 + case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
6909 + case LUA_TTHREAD: {
6910 + lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
6911 + luaE_freethread(L, gco2th(o));
6914 + case LUA_TSTRING: {
6915 + G(L)->strt.nuse--;
6916 + luaM_freemem(L, o, sizestring(gco2ts(o)));
6919 + case LUA_TUSERDATA: {
6920 + luaM_freemem(L, o, sizeudata(gco2u(o)));
6923 + default: lua_assert(0);
6929 +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
6932 +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
6934 + global_State *g = G(L);
6935 + int deadmask = otherwhite(g);
6936 + while ((curr = *p) != NULL && count-- > 0) {
6937 + if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
6938 + sweepwholelist(L, &gco2th(curr)->openupval);
6939 + if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
6940 + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
6941 + makewhite(g, curr); /* make it white (for next cycle) */
6942 + p = &curr->gch.next;
6944 + else { /* must erase `curr' */
6945 + lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
6946 + *p = curr->gch.next;
6947 + if (curr == g->rootgc) /* is the first element of the list? */
6948 + g->rootgc = curr->gch.next; /* adjust first */
6956 +static void checkSizes (lua_State *L) {
6957 + global_State *g = G(L);
6958 + /* check size of string hash */
6959 + if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
6960 + g->strt.size > MINSTRTABSIZE*2)
6961 + luaS_resize(L, g->strt.size/2); /* table is too big */
6962 + /* check size of buffer */
6963 + if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
6964 + size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
6965 + luaZ_resizebuffer(L, &g->buff, newsize);
6970 +static void GCTM (lua_State *L) {
6971 + global_State *g = G(L);
6972 + GCObject *o = g->tmudata->gch.next; /* get first element */
6973 + Udata *udata = rawgco2u(o);
6975 + /* remove udata from `tmudata' */
6976 + if (o == g->tmudata) /* last element? */
6977 + g->tmudata = NULL;
6979 + g->tmudata->gch.next = udata->uv.next;
6980 + udata->uv.next = g->mainthread->next; /* return it to `root' list */
6981 + g->mainthread->next = o;
6983 + tm = fasttm(L, udata->uv.metatable, TM_GC);
6985 + lu_byte oldah = L->allowhook;
6986 + lu_mem oldt = g->GCthreshold;
6987 + L->allowhook = 0; /* stop debug hooks during GC tag method */
6988 + g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
6989 + setobj2s(L, L->top, tm);
6990 + setuvalue(L, L->top+1, udata);
6992 + luaD_call(L, L->top - 2, 0);
6993 + L->allowhook = oldah; /* restore hooks */
6994 + g->GCthreshold = oldt; /* restore threshold */
7000 +** Call all GC tag methods
7002 +void luaC_callGCTM (lua_State *L) {
7003 + while (G(L)->tmudata)
7008 +void luaC_freeall (lua_State *L) {
7009 + global_State *g = G(L);
7011 + g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
7012 + sweepwholelist(L, &g->rootgc);
7013 + for (i = 0; i < g->strt.size; i++) /* free all string lists */
7014 + sweepwholelist(L, &g->strt.hash[i]);
7018 +static void markmt (global_State *g) {
7020 + for (i=0; i<NUM_TAGS; i++)
7021 + if (g->mt[i]) markobject(g, g->mt[i]);
7025 +/* mark root set */
7026 +static void markroot (lua_State *L) {
7027 + global_State *g = G(L);
7029 + g->grayagain = NULL;
7031 + markobject(g, g->mainthread);
7032 + /* make global table be traversed before main stack */
7033 + markvalue(g, gt(g->mainthread));
7034 + markvalue(g, registry(L));
7036 + g->gcstate = GCSpropagate;
7040 +static void remarkupvals (global_State *g) {
7042 + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
7043 + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
7044 + if (isgray(obj2gco(uv)))
7045 + markvalue(g, uv->v);
7050 +static void atomic (lua_State *L) {
7051 + global_State *g = G(L);
7052 + size_t udsize; /* total size of userdata to be finalized */
7053 + /* remark occasional upvalues of (maybe) dead threads */
7055 + /* traverse objects cautch by write barrier and by 'remarkupvals' */
7057 + /* remark weak tables */
7058 + g->gray = g->weak;
7060 + lua_assert(!iswhite(obj2gco(g->mainthread)));
7061 + markobject(g, L); /* mark running thread */
7062 + markmt(g); /* mark basic metatables (again) */
7064 + /* remark gray again */
7065 + g->gray = g->grayagain;
7066 + g->grayagain = NULL;
7068 + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
7069 + marktmu(g); /* mark `preserved' userdata */
7070 + udsize += propagateall(g); /* remark, to propagate `preserveness' */
7071 + cleartable(g->weak); /* remove collected objects from weak tables */
7072 + /* flip current white */
7073 + g->currentwhite = cast_byte(otherwhite(g));
7074 + g->sweepstrgc = 0;
7075 + g->sweepgc = &g->rootgc;
7076 + g->gcstate = GCSsweepstring;
7077 + g->estimate = g->totalbytes - udsize; /* first estimate */
7081 +static l_mem singlestep (lua_State *L) {
7082 + global_State *g = G(L);
7083 + /*lua_checkmemory(L);*/
7084 + switch (g->gcstate) {
7086 + markroot(L); /* start a new collection */
7089 + case GCSpropagate: {
7091 + return propagatemark(g);
7092 + else { /* no more `gray' objects */
7093 + atomic(L); /* finish mark phase */
7097 + case GCSsweepstring: {
7098 + lu_mem old = g->totalbytes;
7099 + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
7100 + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
7101 + g->gcstate = GCSsweep; /* end sweep-string phase */
7102 + lua_assert(old >= g->totalbytes);
7103 + g->estimate -= old - g->totalbytes;
7104 + return GCSWEEPCOST;
7107 + lu_mem old = g->totalbytes;
7108 + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
7109 + if (*g->sweepgc == NULL) { /* nothing more to sweep? */
7111 + g->gcstate = GCSfinalize; /* end sweep phase */
7113 + lua_assert(old >= g->totalbytes);
7114 + g->estimate -= old - g->totalbytes;
7115 + return GCSWEEPMAX*GCSWEEPCOST;
7117 + case GCSfinalize: {
7120 + if (g->estimate > GCFINALIZECOST)
7121 + g->estimate -= GCFINALIZECOST;
7122 + return GCFINALIZECOST;
7125 + g->gcstate = GCSpause; /* end collection */
7130 + default: lua_assert(0); return 0;
7135 +void luaC_step (lua_State *L) {
7136 + global_State *g = G(L);
7137 + l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
7139 + lim = (MAX_LUMEM-1)/2; /* no limit */
7140 + g->gcdept += g->totalbytes - g->GCthreshold;
7142 + lim -= singlestep(L);
7143 + if (g->gcstate == GCSpause)
7145 + } while (lim > 0);
7146 + if (g->gcstate != GCSpause) {
7147 + if (g->gcdept < GCSTEPSIZE)
7148 + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
7150 + g->gcdept -= GCSTEPSIZE;
7151 + g->GCthreshold = g->totalbytes;
7155 + lua_assert(g->totalbytes >= g->estimate);
7161 +void luaC_fullgc (lua_State *L) {
7162 + global_State *g = G(L);
7163 + if (g->gcstate <= GCSpropagate) {
7164 + /* reset sweep marks to sweep all elements (returning them to white) */
7165 + g->sweepstrgc = 0;
7166 + g->sweepgc = &g->rootgc;
7167 + /* reset other collector lists */
7169 + g->grayagain = NULL;
7171 + g->gcstate = GCSsweepstring;
7173 + lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
7174 + /* finish any pending sweep phase */
7175 + while (g->gcstate != GCSfinalize) {
7176 + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
7180 + while (g->gcstate != GCSpause) {
7187 +void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
7188 + global_State *g = G(L);
7189 + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
7190 + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
7191 + lua_assert(ttype(&o->gch) != LUA_TTABLE);
7192 + /* must keep invariant? */
7193 + if (g->gcstate == GCSpropagate)
7194 + reallymarkobject(g, v); /* restore invariant */
7195 + else /* don't mind */
7196 + makewhite(g, o); /* mark as white just to avoid other barriers */
7200 +void luaC_barrierback (lua_State *L, Table *t) {
7201 + global_State *g = G(L);
7202 + GCObject *o = obj2gco(t);
7203 + lua_assert(isblack(o) && !isdead(g, o));
7204 + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
7205 + black2gray(o); /* make table gray (again) */
7206 + t->gclist = g->grayagain;
7211 +void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
7212 + global_State *g = G(L);
7213 + o->gch.next = g->rootgc;
7215 + o->gch.marked = luaC_white(g);
7220 +void luaC_linkupval (lua_State *L, UpVal *uv) {
7221 + global_State *g = G(L);
7222 + GCObject *o = obj2gco(uv);
7223 + o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
7226 + if (g->gcstate == GCSpropagate) {
7227 + gray2black(o); /* closed upvalues need barrier */
7228 + luaC_barrier(L, uv, uv->v);
7230 + else { /* sweep phase: sweep it (turning it into white) */
7232 + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
7238 +++ b/extensions/LUA/lua/lgc.h
7241 +** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $
7242 +** Garbage Collector
7243 +** See Copyright Notice in lua.h
7250 +#include "lobject.h"
7254 +** Possible states of the Garbage Collector
7257 +#define GCSpropagate 1
7258 +#define GCSsweepstring 2
7260 +#define GCSfinalize 4
7264 +** some userful bit tricks
7266 +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
7267 +#define setbits(x,m) ((x) |= (m))
7268 +#define testbits(x,m) ((x) & (m))
7269 +#define bitmask(b) (1<<(b))
7270 +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
7271 +#define l_setbit(x,b) setbits(x, bitmask(b))
7272 +#define resetbit(x,b) resetbits(x, bitmask(b))
7273 +#define testbit(x,b) testbits(x, bitmask(b))
7274 +#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
7275 +#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
7276 +#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
7281 +** Layout for bit use in `marked' field:
7282 +** bit 0 - object is white (type 0)
7283 +** bit 1 - object is white (type 1)
7284 +** bit 2 - object is black
7285 +** bit 3 - for userdata: has been finalized
7286 +** bit 3 - for tables: has weak keys
7287 +** bit 4 - for tables: has weak values
7288 +** bit 5 - object is fixed (should not be collected)
7289 +** bit 6 - object is "super" fixed (only the main thread)
7293 +#define WHITE0BIT 0
7294 +#define WHITE1BIT 1
7296 +#define FINALIZEDBIT 3
7297 +#define KEYWEAKBIT 3
7298 +#define VALUEWEAKBIT 4
7300 +#define SFIXEDBIT 6
7301 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
7304 +#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
7305 +#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
7306 +#define isgray(x) (!isblack(x) && !iswhite(x))
7308 +#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
7309 +#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
7311 +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
7312 +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
7314 +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
7316 +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
7319 +#define luaC_checkGC(L) { \
7320 + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
7321 + if (G(L)->totalbytes >= G(L)->GCthreshold) \
7325 +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
7326 + luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
7328 +#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
7329 + luaC_barrierback(L,t); }
7331 +#define luaC_objbarrier(L,p,o) \
7332 + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
7333 + luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
7335 +#define luaC_objbarriert(L,t,o) \
7336 + { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
7338 +LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
7339 +LUAI_FUNC void luaC_callGCTM (lua_State *L);
7340 +LUAI_FUNC void luaC_freeall (lua_State *L);
7341 +LUAI_FUNC void luaC_step (lua_State *L);
7342 +LUAI_FUNC void luaC_fullgc (lua_State *L);
7343 +LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
7344 +LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
7345 +LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
7346 +LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
7351 +++ b/extensions/LUA/lua/llex.c
7354 +** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $
7355 +** Lexical Analyzer
7356 +** See Copyright Notice in lua.h
7360 +#include <locale.h>
7361 +#include <string.h>
7370 +#include "lobject.h"
7371 +#include "lparser.h"
7372 +#include "lstate.h"
7373 +#include "lstring.h"
7374 +#include "ltable.h"
7379 +#define next(ls) (ls->current = zgetc(ls->z))
7384 +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
7387 +/* ORDER RESERVED */
7388 +const char *const luaX_tokens [] = {
7389 + "and", "break", "do", "else", "elseif",
7390 + "end", "false", "for", "function", "if",
7391 + "in", "local", "nil", "not", "or", "repeat",
7392 + "return", "then", "true", "until", "while",
7393 + "..", "...", "==", ">=", "<=", "~=",
7394 + "<number>", "<name>", "<string>", "<eof>",
7399 +#define save_and_next(ls) (save(ls, ls->current), next(ls))
7402 +static void save (LexState *ls, int c) {
7403 + Mbuffer *b = ls->buff;
7404 + if (b->n + 1 > b->buffsize) {
7406 + if (b->buffsize >= MAX_SIZET/2)
7407 + luaX_lexerror(ls, "lexical element too long", 0);
7408 + newsize = b->buffsize * 2;
7409 + luaZ_resizebuffer(ls->L, b, newsize);
7411 + b->buffer[b->n++] = cast(char, c);
7415 +void luaX_init (lua_State *L) {
7417 + for (i=0; i<NUM_RESERVED; i++) {
7418 + TString *ts = luaS_new(L, luaX_tokens[i]);
7419 + luaS_fix(ts); /* reserved words are never collected */
7420 + lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
7421 + ts->tsv.reserved = cast_byte(i+1); /* reserved word */
7429 +const char *luaX_token2str (LexState *ls, int token) {
7430 + if (token < FIRST_RESERVED) {
7431 + lua_assert(token == cast(unsigned char, token));
7432 + return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
7433 + luaO_pushfstring(ls->L, "%c", token);
7436 + return luaX_tokens[token-FIRST_RESERVED];
7440 +static const char *txtToken (LexState *ls, int token) {
7446 + return luaZ_buffer(ls->buff);
7448 + return luaX_token2str(ls, token);
7453 +void luaX_lexerror (LexState *ls, const char *msg, int token) {
7454 + char buff[MAXSRC];
7455 + luaO_chunkid(buff, getstr(ls->source), MAXSRC);
7456 + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
7458 + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
7459 + luaD_throw(ls->L, LUA_ERRSYNTAX);
7463 +void luaX_syntaxerror (LexState *ls, const char *msg) {
7464 + luaX_lexerror(ls, msg, ls->t.token);
7468 +TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
7469 + lua_State *L = ls->L;
7470 + TString *ts = luaS_newlstr(L, str, l);
7471 + TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
7473 + setbvalue(o, 1); /* make sure `str' will not be collected */
7478 +static void inclinenumber (LexState *ls) {
7479 + int old = ls->current;
7480 + lua_assert(currIsNewline(ls));
7481 + next(ls); /* skip `\n' or `\r' */
7482 + if (currIsNewline(ls) && ls->current != old)
7483 + next(ls); /* skip `\n\r' or `\r\n' */
7484 + if (++ls->linenumber >= MAX_INT)
7485 + luaX_syntaxerror(ls, "chunk has too many lines");
7489 +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
7490 + ls->decpoint = '.';
7492 + ls->lookahead.token = TK_EOS; /* no look-ahead token */
7495 + ls->linenumber = 1;
7497 + ls->source = source;
7498 + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
7499 + next(ls); /* read first char */
7505 +** =======================================================
7506 +** LEXICAL ANALYZER
7507 +** =======================================================
7512 +static int check_next (LexState *ls, const char *set) {
7513 + if (!strchr(set, ls->current))
7515 + save_and_next(ls);
7520 +static void buffreplace (LexState *ls, char from, char to) {
7521 + size_t n = luaZ_bufflen(ls->buff);
7522 + char *p = luaZ_buffer(ls->buff);
7524 + if (p[n] == from) p[n] = to;
7528 +static void trydecpoint (LexState *ls, SemInfo *seminfo) {
7529 + /* format error: try to update decimal point separator */
7530 + char old = ls->decpoint;
7531 + struct lconv *cv = localeconv();
7532 + ls->decpoint = (cv ? cv->decimal_point[0] : '.');
7533 + buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
7534 + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
7535 + /* format error with correct decimal point: no more options */
7536 + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
7537 + luaX_lexerror(ls, "malformed number", TK_NUMBER);
7543 +static void read_numeral (LexState *ls, SemInfo *seminfo) {
7544 + lua_assert(isdigit(ls->current));
7546 + save_and_next(ls);
7547 + } while (isdigit(ls->current) || ls->current == '.');
7548 + if (check_next(ls, "Ee")) /* `E'? */
7549 + check_next(ls, "+-"); /* optional exponent sign */
7550 + while (isalnum(ls->current) || ls->current == '_')
7551 + save_and_next(ls);
7553 + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
7554 + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
7555 + trydecpoint(ls, seminfo); /* try to update decimal point separator */
7559 +static int skip_sep (LexState *ls) {
7561 + int s = ls->current;
7562 + lua_assert(s == '[' || s == ']');
7563 + save_and_next(ls);
7564 + while (ls->current == '=') {
7565 + save_and_next(ls);
7568 + return (ls->current == s) ? count : (-count) - 1;
7572 +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
7574 + (void)(cont); /* avoid warnings when `cont' is not used */
7575 + save_and_next(ls); /* skip 2nd `[' */
7576 + if (currIsNewline(ls)) /* string starts with a newline? */
7577 + inclinenumber(ls); /* skip it */
7579 + switch (ls->current) {
7581 + luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
7582 + "unfinished long comment", TK_EOS);
7583 + break; /* to avoid warnings */
7584 +#if defined(LUA_COMPAT_LSTR)
7586 + if (skip_sep(ls) == sep) {
7587 + save_and_next(ls); /* skip 2nd `[' */
7589 +#if LUA_COMPAT_LSTR == 1
7591 + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
7598 + if (skip_sep(ls) == sep) {
7599 + save_and_next(ls); /* skip 2nd `]' */
7600 +#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
7602 + if (sep == 0 && cont >= 0) break;
7611 + inclinenumber(ls);
7612 + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
7616 + if (seminfo) save_and_next(ls);
7622 + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
7623 + luaZ_bufflen(ls->buff) - 2*(2 + sep));
7627 +static void read_string (LexState *ls, int del, SemInfo *seminfo) {
7628 + save_and_next(ls);
7629 + while (ls->current != del) {
7630 + switch (ls->current) {
7632 + luaX_lexerror(ls, "unfinished string", TK_EOS);
7633 + continue; /* to avoid warnings */
7636 + luaX_lexerror(ls, "unfinished string", TK_STRING);
7637 + continue; /* to avoid warnings */
7640 + next(ls); /* do not save the `\' */
7641 + switch (ls->current) {
7642 + case 'a': c = '\a'; break;
7643 + case 'b': c = '\b'; break;
7644 + case 'f': c = '\f'; break;
7645 + case 'n': c = '\n'; break;
7646 + case 'r': c = '\r'; break;
7647 + case 't': c = '\t'; break;
7648 + case 'v': c = '\v'; break;
7649 + case '\n': /* go through */
7650 + case '\r': save(ls, '\n'); inclinenumber(ls); continue;
7651 + case EOZ: continue; /* will raise an error next loop */
7653 + if (!isdigit(ls->current))
7654 + save_and_next(ls); /* handles \\, \", \', and \? */
7659 + c = 10*c + (ls->current-'0');
7661 + } while (++i<3 && isdigit(ls->current));
7662 + if (c > UCHAR_MAX)
7663 + luaX_lexerror(ls, "escape sequence too large", TK_STRING);
7674 + save_and_next(ls);
7677 + save_and_next(ls); /* skip delimiter */
7678 + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
7679 + luaZ_bufflen(ls->buff) - 2);
7683 +static int llex (LexState *ls, SemInfo *seminfo) {
7684 + luaZ_resetbuffer(ls->buff);
7686 + switch (ls->current) {
7689 + inclinenumber(ls);
7694 + if (ls->current != '-') return '-';
7695 + /* else is a comment */
7697 + if (ls->current == '[') {
7698 + int sep = skip_sep(ls);
7699 + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
7701 + read_long_string(ls, NULL, sep); /* long comment */
7702 + luaZ_resetbuffer(ls->buff);
7706 + /* else short comment */
7707 + while (!currIsNewline(ls) && ls->current != EOZ)
7712 + int sep = skip_sep(ls);
7714 + read_long_string(ls, seminfo, sep);
7717 + else if (sep == -1) return '[';
7718 + else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
7722 + if (ls->current != '=') return '=';
7723 + else { next(ls); return TK_EQ; }
7727 + if (ls->current != '=') return '<';
7728 + else { next(ls); return TK_LE; }
7732 + if (ls->current != '=') return '>';
7733 + else { next(ls); return TK_GE; }
7737 + if (ls->current != '=') return '~';
7738 + else { next(ls); return TK_NE; }
7742 + read_string(ls, ls->current, seminfo);
7746 + save_and_next(ls);
7747 + if (check_next(ls, ".")) {
7748 + if (check_next(ls, "."))
7749 + return TK_DOTS; /* ... */
7750 + else return TK_CONCAT; /* .. */
7752 + else if (!isdigit(ls->current)) return '.';
7754 + read_numeral(ls, seminfo);
7762 + if (isspace(ls->current)) {
7763 + lua_assert(!currIsNewline(ls));
7767 + else if (isdigit(ls->current)) {
7768 + read_numeral(ls, seminfo);
7771 + else if (isalpha(ls->current) || ls->current == '_') {
7772 + /* identifier or reserved word */
7775 + save_and_next(ls);
7776 + } while (isalnum(ls->current) || ls->current == '_');
7777 + ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
7778 + luaZ_bufflen(ls->buff));
7779 + if (ts->tsv.reserved > 0) /* reserved word? */
7780 + return ts->tsv.reserved - 1 + FIRST_RESERVED;
7787 + int c = ls->current;
7789 + return c; /* single-char tokens (+ - / ...) */
7797 +void luaX_next (LexState *ls) {
7798 + ls->lastline = ls->linenumber;
7799 + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
7800 + ls->t = ls->lookahead; /* use this one */
7801 + ls->lookahead.token = TK_EOS; /* and discharge it */
7804 + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
7808 +void luaX_lookahead (LexState *ls) {
7809 + lua_assert(ls->lookahead.token == TK_EOS);
7810 + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
7814 +++ b/extensions/LUA/lua/llex.h
7817 +** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $
7818 +** Lexical Analyzer
7819 +** See Copyright Notice in lua.h
7825 +#include "lobject.h"
7829 +#define FIRST_RESERVED 257
7831 +/* maximum length of a reserved word */
7832 +#define TOKEN_LEN (sizeof("function")/sizeof(char))
7836 +* WARNING: if you change the order of this enumeration,
7837 +* grep "ORDER RESERVED"
7840 + /* terminal symbols denoted by reserved words */
7841 + TK_AND = FIRST_RESERVED, TK_BREAK,
7842 + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
7843 + TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
7844 + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
7845 + /* other terminal symbols */
7846 + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
7847 + TK_NAME, TK_STRING, TK_EOS
7850 +/* number of reserved words */
7851 +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
7854 +/* array with token `names' */
7855 +LUAI_DATA const char *const luaX_tokens [];
7861 +} SemInfo; /* semantics information */
7864 +typedef struct Token {
7870 +typedef struct LexState {
7871 + int current; /* current character (charint) */
7872 + int linenumber; /* input line counter */
7873 + int lastline; /* line of last token `consumed' */
7874 + Token t; /* current token */
7875 + Token lookahead; /* look ahead token */
7876 + struct FuncState *fs; /* `FuncState' is private to the parser */
7877 + struct lua_State *L;
7878 + ZIO *z; /* input stream */
7879 + Mbuffer *buff; /* buffer for tokens */
7880 + TString *source; /* current source name */
7881 + char decpoint; /* locale decimal point */
7885 +LUAI_FUNC void luaX_init (lua_State *L);
7886 +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
7888 +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
7889 +LUAI_FUNC void luaX_next (LexState *ls);
7890 +LUAI_FUNC void luaX_lookahead (LexState *ls);
7891 +LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
7892 +LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
7893 +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
7898 +++ b/extensions/LUA/lua/llimits.h
7901 +** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $
7902 +** Limits, basic types, and some other `installation-dependent' definitions
7903 +** See Copyright Notice in lua.h
7909 +#include <stddef.h>
7910 +#include <limits.h>
7914 +typedef LUAI_UINT32 lu_int32;
7916 +typedef LUAI_UMEM lu_mem;
7918 +typedef LUAI_MEM l_mem;
7922 +/* chars used as small naturals (so that `char' is reserved for characters) */
7923 +typedef unsigned char lu_byte;
7926 +#define MAX_SIZET ((size_t)(~(size_t)0)-2)
7928 +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
7931 +#define MAX_INT (LUA_INT_MAX-2) /* maximum value of an int (-2 for safety) */
7934 +** conversion of pointer to integer
7935 +** this is for hashing only; there is no problem if the integer
7936 +** cannot hold the whole pointer value
7938 +#define IntPoint(p) ((unsigned int)(lu_mem)(p))
7942 +/* type to ensure maximum alignment */
7943 +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
7946 +/* result of a `usual argument conversion' over lua_Number */
7947 +typedef LUAI_UACNUMBER l_uacNumber;
7950 +/* internal assertions for in-house debugging */
7953 +#define check_exp(c,e) (lua_assert(c), (e))
7954 +#define api_check(l,e) lua_assert(e)
7958 +#define lua_assert(c) ((void)0)
7959 +#define check_exp(c,e) (e)
7960 +#define api_check luai_apicheck
7966 +#define UNUSED(x) ((void)(x)) /* to avoid warnings */
7971 +#define cast(t, exp) ((t)(exp))
7974 +#define cast_byte(i) cast(lu_byte, (i))
7975 +#define cast_num(i) cast(lua_Number, (i))
7976 +#define cast_int(i) cast(int, (i))
7981 +** type for virtual-machine instructions
7982 +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
7984 +typedef lu_int32 Instruction;
7988 +/* maximum stack for a Lua function */
7989 +#define MAXSTACK 250
7993 +/* minimum size for the string table (must be power of 2) */
7994 +#ifndef MINSTRTABSIZE
7995 +#define MINSTRTABSIZE 32
7999 +/* minimum size for string buffer */
8000 +#ifndef LUA_MINBUFFER
8001 +#define LUA_MINBUFFER 32
8006 +#define lua_lock(L) ((void) 0)
8007 +#define lua_unlock(L) ((void) 0)
8010 +#ifndef luai_threadyield
8011 +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
8016 +** macro to control inclusion of some hard tests on stack reallocation
8018 +#ifndef HARDSTACKTESTS
8019 +#define condhardstacktests(x) ((void)0)
8021 +#define condhardstacktests(x) x
8026 +++ b/extensions/LUA/lua/lmem.c
8029 +** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $
8030 +** Interface to Memory Manager
8031 +** See Copyright Notice in lua.h
8035 +#include <stddef.h>
8042 +#include "ldebug.h"
8045 +#include "lobject.h"
8046 +#include "lstate.h"
8051 +** About the realloc function:
8052 +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
8053 +** (`osize' is the old size, `nsize' is the new size)
8055 +** Lua ensures that (ptr == NULL) iff (osize == 0).
8057 +** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
8059 +** * frealloc(ud, p, x, 0) frees the block `p'
8060 +** (in this specific case, frealloc must return NULL).
8061 +** particularly, frealloc(ud, NULL, 0, 0) does nothing
8062 +** (which is equivalent to free(NULL) in ANSI C)
8064 +** frealloc returns NULL if it cannot create or reallocate the area
8065 +** (any reallocation to an equal or smaller size cannot fail!)
8070 +#define MINSIZEARRAY 4
8073 +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
8074 + int limit, const char *errormsg) {
8077 + if (*size >= limit/2) { /* cannot double it? */
8078 + if (*size >= limit) /* cannot grow even a little? */
8079 + luaG_runerror(L, errormsg);
8080 + newsize = limit; /* still have at least one free place */
8083 + newsize = (*size)*2;
8084 + if (newsize < MINSIZEARRAY)
8085 + newsize = MINSIZEARRAY; /* minimum size */
8087 + newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
8088 + *size = newsize; /* update only when everything else is OK */
8093 +void *luaM_toobig (lua_State *L) {
8094 + luaG_runerror(L, "memory allocation error: block too big");
8095 + return NULL; /* to avoid warnings */
8101 +** generic allocation routine.
8103 +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
8104 + global_State *g = G(L);
8105 + lua_assert((osize == 0) == (block == NULL));
8106 + block = (*g->frealloc)(g->ud, block, osize, nsize);
8107 + if (block == NULL && nsize > 0)
8108 + luaD_throw(L, LUA_ERRMEM);
8109 + lua_assert((nsize == 0) == (block == NULL));
8110 + g->totalbytes = (g->totalbytes - osize) + nsize;
8115 +++ b/extensions/LUA/lua/lmem.h
8118 +** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
8119 +** Interface to Memory Manager
8120 +** See Copyright Notice in lua.h
8127 +#include <stddef.h>
8129 +#include "llimits.h"
8132 +#define MEMERRMSG "not enough memory"
8135 +#define luaM_reallocv(L,b,on,n,e) \
8136 + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
8137 + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
8140 +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
8141 +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
8142 +#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))
8144 +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
8145 +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
8146 +#define luaM_newvector(L,n,t) \
8147 + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
8149 +#define luaM_growvector(L,v,nelems,size,t,limit,e) \
8150 + if ((nelems)+1 > (size)) \
8151 + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
8153 +#define luaM_reallocvector(L, v,oldn,n,t) \
8154 + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
8157 +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
8159 +LUAI_FUNC void *luaM_toobig (lua_State *L);
8160 +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
8161 + size_t size_elem, int limit,
8162 + const char *errormsg);
8167 +++ b/extensions/LUA/lua/lobject.c
8170 +** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
8171 +** Some generic functions over Lua objects
8172 +** See Copyright Notice in lua.h
8175 +#include <stdarg.h>
8179 +#include <stdlib.h>
8180 +#include <string.h>
8189 +#include "lobject.h"
8190 +#include "lstate.h"
8191 +#include "lstring.h"
8196 +const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
8200 +** converts an integer to a "floating point byte", represented as
8201 +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
8202 +** eeeee != 0 and (xxx) otherwise.
8204 +int luaO_int2fb (unsigned int x) {
8205 + int e = 0; /* expoent */
8210 + if (x < 8) return x;
8211 + else return ((e+1) << 3) | (cast_int(x) - 8);
8215 +/* converts back */
8216 +int luaO_fb2int (int x) {
8217 + int e = (x >> 3) & 31;
8218 + if (e == 0) return x;
8219 + else return ((x & 7)+8) << (e - 1);
8223 +int luaO_log2 (unsigned int x) {
8224 + static const lu_byte log_2[256] = {
8225 + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
8226 + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
8227 + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8228 + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8229 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8230 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8231 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8232 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
8235 + while (x >= 256) { l += 8; x >>= 8; }
8236 + return l + log_2[x];
8241 +int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
8242 + if (ttype(t1) != ttype(t2)) return 0;
8243 + else switch (ttype(t1)) {
8247 + return luai_numeq(nvalue(t1), nvalue(t2));
8248 + case LUA_TBOOLEAN:
8249 + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
8250 + case LUA_TLIGHTUSERDATA:
8251 + return pvalue(t1) == pvalue(t2);
8253 + lua_assert(iscollectable(t1));
8254 + return gcvalue(t1) == gcvalue(t2);
8259 +int luaO_str2d (const char *s, lua_Number *result) {
8261 + *result = lua_str2number(s, &endptr);
8262 + if (endptr == s) return 0; /* conversion failed */
8263 + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
8264 + *result = cast_num(strtoul(s, &endptr, 16));
8265 + if (*endptr == '\0') return 1; /* most common case */
8266 + while (isspace(cast(unsigned char, *endptr))) endptr++;
8267 + if (*endptr != '\0') return 0; /* invalid trailing characters? */
8273 +static void pushstr (lua_State *L, const char *str) {
8274 + setsvalue2s(L, L->top, luaS_new(L, str));
8279 +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
8280 +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
8284 + const char *e = strchr(fmt, '%');
8285 + if (e == NULL) break;
8286 + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
8290 + const char *s = va_arg(argp, char *);
8291 + if (s == NULL) s = "(null)";
8297 + buff[0] = cast(char, va_arg(argp, int));
8303 + setnvalue(L->top, cast_num(va_arg(argp, int)));
8308 + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
8313 + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
8314 + sprintf(buff, "%p", va_arg(argp, void *));
8335 + luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
8337 + return svalue(L->top - 1);
8341 +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
8344 + va_start(argp, fmt);
8345 + msg = luaO_pushvfstring(L, fmt, argp);
8351 +void luaO_chunkid (char *out, const char *source, size_t bufflen) {
8352 + if (*source == '=') {
8353 + strncpy(out, source+1, bufflen); /* remove first char */
8354 + out[bufflen-1] = '\0'; /* ensures null termination */
8356 + else { /* out = "source", or "...source" */
8357 + if (*source == '@') {
8359 + source++; /* skip the `@' */
8360 + bufflen -= sizeof(" '...' ");
8361 + l = strlen(source);
8363 + if (l > bufflen) {
8364 + source += (l-bufflen); /* get last part of file name */
8365 + strcat(out, "...");
8367 + strcat(out, source);
8369 + else { /* out = [string "string"] */
8370 + size_t len = strcspn(source, "\n\r"); /* stop at first newline */
8371 + bufflen -= sizeof(" [string \"...\"] ");
8372 + if (len > bufflen) len = bufflen;
8373 + strcpy(out, "[string \"");
8374 + if (source[len] != '\0') { /* must truncate? */
8375 + strncat(out, source, len);
8376 + strcat(out, "...");
8379 + strcat(out, source);
8380 + strcat(out, "\"]");
8385 +++ b/extensions/LUA/lua/lobject.h
8388 +** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $
8389 +** Type definitions for Lua objects
8390 +** See Copyright Notice in lua.h
8398 +#include <stdarg.h>
8401 +#include "llimits.h"
8405 +/* tags for values visible from Lua */
8406 +#define LAST_TAG LUA_TTHREAD
8408 +#define NUM_TAGS (LAST_TAG+1)
8412 +** Extra tags for non-values
8414 +#define LUA_TPROTO (LAST_TAG+1)
8415 +#define LUA_TUPVAL (LAST_TAG+2)
8416 +#define LUA_TDEADKEY (LAST_TAG+3)
8420 +** Union of all collectable objects
8422 +typedef union GCObject GCObject;
8426 +** Common Header for all collectable objects (in macro form, to be
8427 +** included in other objects)
8429 +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
8433 +** Common header in struct form
8435 +typedef struct GCheader {
8443 +** Union of all Lua values
8457 +#define TValuefields Value value; int tt
8459 +typedef struct lua_TValue {
8464 +/* Macros to test type */
8465 +#define ttisnil(o) (ttype(o) == LUA_TNIL)
8466 +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
8467 +#define ttisstring(o) (ttype(o) == LUA_TSTRING)
8468 +#define ttistable(o) (ttype(o) == LUA_TTABLE)
8469 +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
8470 +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
8471 +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
8472 +#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
8473 +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
8475 +/* Macros to access values */
8476 +#define ttype(o) ((o)->tt)
8477 +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
8478 +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
8479 +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
8480 +#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
8481 +#define tsvalue(o) (&rawtsvalue(o)->tsv)
8482 +#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
8483 +#define uvalue(o) (&rawuvalue(o)->uv)
8484 +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
8485 +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
8486 +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
8487 +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
8489 +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
8492 +** for internal debug only
8494 +#define checkconsistency(obj) \
8495 + lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
8497 +#define checkliveness(g,obj) \
8498 + lua_assert(!iscollectable(obj) || \
8499 + ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
8502 +/* Macros to set values */
8503 +#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
8505 +#define setnvalue(obj,x) \
8506 + { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
8508 +#define setpvalue(obj,x) \
8509 + { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
8511 +#define setbvalue(obj,x) \
8512 + { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
8514 +#define setsvalue(L,obj,x) \
8515 + { TValue *i_o=(obj); \
8516 + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
8517 + checkliveness(G(L),i_o); }
8519 +#define setuvalue(L,obj,x) \
8520 + { TValue *i_o=(obj); \
8521 + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
8522 + checkliveness(G(L),i_o); }
8524 +#define setthvalue(L,obj,x) \
8525 + { TValue *i_o=(obj); \
8526 + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
8527 + checkliveness(G(L),i_o); }
8529 +#define setclvalue(L,obj,x) \
8530 + { TValue *i_o=(obj); \
8531 + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
8532 + checkliveness(G(L),i_o); }
8534 +#define sethvalue(L,obj,x) \
8535 + { TValue *i_o=(obj); \
8536 + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
8537 + checkliveness(G(L),i_o); }
8539 +#define setptvalue(L,obj,x) \
8540 + { TValue *i_o=(obj); \
8541 + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
8542 + checkliveness(G(L),i_o); }
8547 +#define setobj(L,obj1,obj2) \
8548 + { const TValue *o2=(obj2); TValue *o1=(obj1); \
8549 + o1->value = o2->value; o1->tt=o2->tt; \
8550 + checkliveness(G(L),o1); }
8554 +** different types of sets, according to destination
8557 +/* from stack to (same) stack */
8558 +#define setobjs2s setobj
8559 +/* to stack (not from same stack) */
8560 +#define setobj2s setobj
8561 +#define setsvalue2s setsvalue
8562 +#define sethvalue2s sethvalue
8563 +#define setptvalue2s setptvalue
8564 +/* from table to same table */
8565 +#define setobjt2t setobj
8567 +#define setobj2t setobj
8568 +/* to new object */
8569 +#define setobj2n setobj
8570 +#define setsvalue2n setsvalue
8572 +#define setttype(obj, tt) (ttype(obj) = (tt))
8575 +#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
8579 +typedef TValue *StkId; /* index to stack elements */
8583 +** String headers for string table
8585 +typedef union TString {
8586 + L_Umaxalign dummy; /* ensures maximum alignment for strings */
8590 + unsigned int hash;
8596 +#define getstr(ts) cast(const char *, (ts) + 1)
8597 +#define svalue(o) getstr(rawtsvalue(o))
8601 +typedef union Udata {
8602 + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
8605 + struct Table *metatable;
8606 + struct Table *env;
8615 +** Function Prototypes
8617 +typedef struct Proto {
8619 + TValue *k; /* constants used by the function */
8620 + Instruction *code;
8621 + struct Proto **p; /* functions defined inside the function */
8622 + int *lineinfo; /* map from opcodes to source lines */
8623 + struct LocVar *locvars; /* information about local variables */
8624 + TString **upvalues; /* upvalue names */
8627 + int sizek; /* size of `k' */
8630 + int sizep; /* size of `p' */
8633 + int lastlinedefined;
8635 + lu_byte nups; /* number of upvalues */
8636 + lu_byte numparams;
8637 + lu_byte is_vararg;
8638 + lu_byte maxstacksize;
8642 +/* masks for new-style vararg */
8643 +#define VARARG_HASARG 1
8644 +#define VARARG_ISVARARG 2
8645 +#define VARARG_NEEDSARG 4
8648 +typedef struct LocVar {
8650 + int startpc; /* first point where variable is active */
8651 + int endpc; /* first point where variable is dead */
8660 +typedef struct UpVal {
8662 + TValue *v; /* points to stack or to its own value */
8664 + TValue value; /* the value (when closed) */
8665 + struct { /* double linked list (when open) */
8666 + struct UpVal *prev;
8667 + struct UpVal *next;
8677 +#define ClosureHeader \
8678 + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
8681 +typedef struct CClosure {
8684 + TValue upvalue[1];
8688 +typedef struct LClosure {
8695 +typedef union Closure {
8701 +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
8702 +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
8709 +typedef union TKey {
8712 + struct Node *next; /* for chaining */
8718 +typedef struct Node {
8724 +typedef struct Table {
8726 + lu_byte flags; /* 1<<p means tagmethod(p) is not present */
8727 + lu_byte lsizenode; /* log2 of size of `node' array */
8728 + struct Table *metatable;
8729 + TValue *array; /* array part */
8731 + Node *lastfree; /* any free position is before this position */
8733 + int sizearray; /* size of `array' array */
8739 +** `module' operation for hashing (size is always a power of 2)
8741 +#define lmod(s,size) \
8742 + (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
8745 +#define twoto(x) (1<<(x))
8746 +#define sizenode(t) (twoto((t)->lsizenode))
8749 +#define luaO_nilobject (&luaO_nilobject_)
8751 +LUAI_DATA const TValue luaO_nilobject_;
8753 +#define ceillog2(x) (luaO_log2((x)-1) + 1)
8755 +LUAI_FUNC int luaO_log2 (unsigned int x);
8756 +LUAI_FUNC int luaO_int2fb (unsigned int x);
8757 +LUAI_FUNC int luaO_fb2int (int x);
8758 +LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
8759 +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
8760 +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
8762 +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
8763 +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
8769 +++ b/extensions/LUA/lua/lopcodes.c
8772 +** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
8773 +** See Copyright Notice in lua.h
8781 +#include "lopcodes.h"
8786 +const char *const luaP_opnames[NUM_OPCODES+1] = {
8829 +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
8831 +const lu_byte luaP_opmodes[NUM_OPCODES] = {
8832 +/* T A B C mode opcode */
8833 + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
8834 + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
8835 + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
8836 + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
8837 + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
8838 + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
8839 + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
8840 + ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
8841 + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
8842 + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
8843 + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
8844 + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
8845 + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
8846 + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
8847 + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
8848 + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
8849 + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
8850 + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
8851 + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
8852 + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
8853 + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
8854 + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
8855 + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
8856 + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
8857 + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
8858 + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
8859 + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
8860 + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
8861 + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
8862 + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
8863 + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
8864 + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
8865 + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
8866 + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
8867 + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
8868 + ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
8869 + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
8870 + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
8874 +++ b/extensions/LUA/lua/lopcodes.h
8877 +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
8878 +** Opcodes for Lua virtual machine
8879 +** See Copyright Notice in lua.h
8885 +#include "llimits.h"
8888 +/*===========================================================================
8889 + We assume that instructions are unsigned numbers.
8890 + All instructions have an opcode in the first 6 bits.
8891 + Instructions can have the following fields:
8895 + `Bx' : 18 bits (`B' and `C' together)
8898 + A signed argument is represented in excess K; that is, the number
8899 + value is the unsigned value minus K. K is exactly the maximum value
8900 + for that argument (so that -max is represented by 0, and +max is
8901 + represented by 2*max), which is half the maximum for the corresponding
8902 + unsigned argument.
8903 +===========================================================================*/
8906 +enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
8910 +** size and position of opcode arguments.
8914 +#define SIZE_Bx (SIZE_C + SIZE_B)
8920 +#define POS_A (POS_OP + SIZE_OP)
8921 +#define POS_C (POS_A + SIZE_A)
8922 +#define POS_B (POS_C + SIZE_C)
8923 +#define POS_Bx POS_C
8927 +** limits for opcode arguments.
8928 +** we use (signed) int to manipulate most arguments,
8929 +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
8931 +#if SIZE_Bx < LUAI_BITSINT-1
8932 +#define MAXARG_Bx ((1<<SIZE_Bx)-1)
8933 +#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
8935 +#define MAXARG_Bx MAX_INT
8936 +#define MAXARG_sBx MAX_INT
8940 +#define MAXARG_A ((1<<SIZE_A)-1)
8941 +#define MAXARG_B ((1<<SIZE_B)-1)
8942 +#define MAXARG_C ((1<<SIZE_C)-1)
8945 +/* creates a mask with `n' 1 bits at position `p' */
8946 +#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
8948 +/* creates a mask with `n' 0 bits at position `p' */
8949 +#define MASK0(n,p) (~MASK1(n,p))
8952 +** the following macros help to manipulate instructions
8955 +#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
8956 +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
8957 + ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
8959 +#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
8960 +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
8961 + ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
8963 +#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
8964 +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
8965 + ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
8967 +#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
8968 +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
8969 + ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
8971 +#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
8972 +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
8973 + ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
8975 +#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
8976 +#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
8979 +#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
8980 + | (cast(Instruction, a)<<POS_A) \
8981 + | (cast(Instruction, b)<<POS_B) \
8982 + | (cast(Instruction, c)<<POS_C))
8984 +#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
8985 + | (cast(Instruction, a)<<POS_A) \
8986 + | (cast(Instruction, bc)<<POS_Bx))
8990 +** Macros to operate RK indices
8993 +/* this bit 1 means constant (0 means register) */
8994 +#define BITRK (1 << (SIZE_B - 1))
8996 +/* test whether value is a constant */
8997 +#define ISK(x) ((x) & BITRK)
8999 +/* gets the index of the constant */
9000 +#define INDEXK(r) ((int)(r) & ~BITRK)
9002 +#define MAXINDEXRK (BITRK - 1)
9004 +/* code a constant index as a RK value */
9005 +#define RKASK(x) ((x) | BITRK)
9009 +** invalid register that fits in 8 bits
9011 +#define NO_REG MAXARG_A
9016 +** Kst(x) - constant (in constant table)
9017 +** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
9022 +** grep "ORDER OP" if you change these enums
9026 +/*----------------------------------------------------------------------
9027 +name args description
9028 +------------------------------------------------------------------------*/
9029 +OP_MOVE,/* A B R(A) := R(B) */
9030 +OP_LOADK,/* A Bx R(A) := Kst(Bx) */
9031 +OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
9032 +OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
9033 +OP_GETUPVAL,/* A B R(A) := UpValue[B] */
9035 +OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
9036 +OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
9038 +OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
9039 +OP_SETUPVAL,/* A B UpValue[B] := R(A) */
9040 +OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
9042 +OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
9044 +OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
9046 +OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
9047 +OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
9048 +OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
9049 +OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
9050 +OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
9051 +OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
9052 +OP_UNM,/* A B R(A) := -R(B) */
9053 +OP_NOT,/* A B R(A) := not R(B) */
9054 +OP_LEN,/* A B R(A) := length of R(B) */
9056 +OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
9058 +OP_JMP,/* sBx pc+=sBx */
9060 +OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
9061 +OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
9062 +OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
9064 +OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
9065 +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
9067 +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
9068 +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
9069 +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
9071 +OP_FORLOOP,/* A sBx R(A)+=R(A+2);
9072 + if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
9073 +OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
9075 +OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
9076 + if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
9077 +OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
9079 +OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
9080 +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
9082 +OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
9086 +#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
9090 +/*===========================================================================
9092 + (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
9093 + and can be 0: OP_CALL then sets `top' to last_result+1, so
9094 + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
9096 + (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
9097 + set top (like in OP_CALL with C == 0).
9099 + (*) In OP_RETURN, if (B == 0) then return up to `top'
9101 + (*) In OP_SETLIST, if (B == 0) then B = `top';
9102 + if (C == 0) then next `instruction' is real C
9104 + (*) For comparisons, A specifies what condition the test should accept
9107 + (*) All `skips' (pc++) assume that next instruction is a jump
9108 +===========================================================================*/
9112 +** masks for instruction properties. The format is:
9113 +** bits 0-1: op mode
9114 +** bits 2-3: C arg mode
9115 +** bits 4-5: B arg mode
9116 +** bit 6: instruction set register A
9117 +** bit 7: operator is a test
9121 + OpArgN, /* argument is not used */
9122 + OpArgU, /* argument is used */
9123 + OpArgR, /* argument is a register or a jump offset */
9124 + OpArgK /* argument is a constant or register/constant */
9127 +LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
9129 +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
9130 +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
9131 +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
9132 +#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
9133 +#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
9136 +LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
9139 +/* number of list items to accumulate before a SETLIST instruction */
9140 +#define LFIELDS_PER_FLUSH 50
9145 +++ b/extensions/LUA/lua/lparser.c
9148 +** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
9150 +** See Copyright Notice in lua.h
9154 +#include <string.h>
9162 +#include "ldebug.h"
9167 +#include "lobject.h"
9168 +#include "lopcodes.h"
9169 +#include "lparser.h"
9170 +#include "lstate.h"
9171 +#include "lstring.h"
9172 +#include "ltable.h"
9176 +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
9178 +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
9180 +#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
9184 +** nodes for block list (list of active blocks)
9186 +typedef struct BlockCnt {
9187 + struct BlockCnt *previous; /* chain */
9188 + int breaklist; /* list of jumps out of this loop */
9189 + lu_byte nactvar; /* # active locals outside the breakable structure */
9190 + lu_byte upval; /* true if some variable in the block is an upvalue */
9191 + lu_byte isbreakable; /* true if `block' is a loop */
9197 +** prototypes for recursive non-terminal functions
9199 +static void chunk (LexState *ls);
9200 +static void expr (LexState *ls, expdesc *v);
9203 +static void anchor_token (LexState *ls) {
9204 + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
9205 + TString *ts = ls->t.seminfo.ts;
9206 + luaX_newstring(ls, getstr(ts), ts->tsv.len);
9211 +static void error_expected (LexState *ls, int token) {
9212 + luaX_syntaxerror(ls,
9213 + luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
9217 +static void errorlimit (FuncState *fs, int limit, const char *what) {
9218 + const char *msg = (fs->f->linedefined == 0) ?
9219 + luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
9220 + luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
9221 + fs->f->linedefined, limit, what);
9222 + luaX_lexerror(fs->ls, msg, 0);
9226 +static int testnext (LexState *ls, int c) {
9227 + if (ls->t.token == c) {
9235 +static void check (LexState *ls, int c) {
9236 + if (ls->t.token != c)
9237 + error_expected(ls, c);
9240 +static void checknext (LexState *ls, int c) {
9246 +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
9250 +static void check_match (LexState *ls, int what, int who, int where) {
9251 + if (!testnext(ls, what)) {
9252 + if (where == ls->linenumber)
9253 + error_expected(ls, what);
9255 + luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
9256 + LUA_QS " expected (to close " LUA_QS " at line %d)",
9257 + luaX_token2str(ls, what), luaX_token2str(ls, who), where));
9263 +static TString *str_checkname (LexState *ls) {
9265 + check(ls, TK_NAME);
9266 + ts = ls->t.seminfo.ts;
9272 +static void init_exp (expdesc *e, expkind k, int i) {
9273 + e->f = e->t = NO_JUMP;
9279 +static void codestring (LexState *ls, expdesc *e, TString *s) {
9280 + init_exp(e, VK, luaK_stringK(ls->fs, s));
9284 +static void checkname(LexState *ls, expdesc *e) {
9285 + codestring(ls, e, str_checkname(ls));
9289 +static int registerlocalvar (LexState *ls, TString *varname) {
9290 + FuncState *fs = ls->fs;
9292 + int oldsize = f->sizelocvars;
9293 + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
9294 + LocVar, SHRT_MAX, "too many local variables");
9295 + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
9296 + f->locvars[fs->nlocvars].varname = varname;
9297 + luaC_objbarrier(ls->L, f, varname);
9298 + return fs->nlocvars++;
9302 +#define new_localvarliteral(ls,v,n) \
9303 + new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
9306 +static void new_localvar (LexState *ls, TString *name, int n) {
9307 + FuncState *fs = ls->fs;
9308 + luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
9309 + fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
9313 +static void adjustlocalvars (LexState *ls, int nvars) {
9314 + FuncState *fs = ls->fs;
9315 + fs->nactvar = cast_byte(fs->nactvar + nvars);
9316 + for (; nvars; nvars--) {
9317 + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
9322 +static void removevars (LexState *ls, int tolevel) {
9323 + FuncState *fs = ls->fs;
9324 + while (fs->nactvar > tolevel)
9325 + getlocvar(fs, --fs->nactvar).endpc = fs->pc;
9329 +static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
9332 + int oldsize = f->sizeupvalues;
9333 + for (i=0; i<f->nups; i++) {
9334 + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
9335 + lua_assert(f->upvalues[i] == name);
9340 + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
9341 + luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
9342 + TString *, MAX_INT, "");
9343 + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
9344 + f->upvalues[f->nups] = name;
9345 + luaC_objbarrier(fs->L, f, name);
9346 + lua_assert(v->k == VLOCAL || v->k == VUPVAL);
9347 + fs->upvalues[f->nups].k = cast_byte(v->k);
9348 + fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
9353 +static int searchvar (FuncState *fs, TString *n) {
9355 + for (i=fs->nactvar-1; i >= 0; i--) {
9356 + if (n == getlocvar(fs, i).varname)
9359 + return -1; /* not found */
9363 +static void markupval (FuncState *fs, int level) {
9364 + BlockCnt *bl = fs->bl;
9365 + while (bl && bl->nactvar > level) bl = bl->previous;
9366 + if (bl) bl->upval = 1;
9370 +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
9371 + if (fs == NULL) { /* no more levels? */
9372 + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
9376 + int v = searchvar(fs, n); /* look up at current level */
9378 + init_exp(var, VLOCAL, v);
9380 + markupval(fs, v); /* local will be used as an upval */
9383 + else { /* not found at current level; try upper one */
9384 + if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
9386 + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
9387 + var->k = VUPVAL; /* upvalue in this level */
9394 +static void singlevar (LexState *ls, expdesc *var) {
9395 + TString *varname = str_checkname(ls);
9396 + FuncState *fs = ls->fs;
9397 + if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
9398 + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
9402 +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
9403 + FuncState *fs = ls->fs;
9404 + int extra = nvars - nexps;
9405 + if (hasmultret(e->k)) {
9406 + extra++; /* includes call itself */
9407 + if (extra < 0) extra = 0;
9408 + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
9409 + if (extra > 1) luaK_reserveregs(fs, extra-1);
9412 + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
9414 + int reg = fs->freereg;
9415 + luaK_reserveregs(fs, extra);
9416 + luaK_nil(fs, reg, extra);
9422 +static void enterlevel (LexState *ls) {
9423 + if (++ls->L->nCcalls > LUAI_MAXCCALLS)
9424 + luaX_lexerror(ls, "chunk has too many syntax levels", 0);
9428 +#define leavelevel(ls) ((ls)->L->nCcalls--)
9431 +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
9432 + bl->breaklist = NO_JUMP;
9433 + bl->isbreakable = isbreakable;
9434 + bl->nactvar = fs->nactvar;
9436 + bl->previous = fs->bl;
9438 + lua_assert(fs->freereg == fs->nactvar);
9442 +static void leaveblock (FuncState *fs) {
9443 + BlockCnt *bl = fs->bl;
9444 + fs->bl = bl->previous;
9445 + removevars(fs->ls, bl->nactvar);
9447 + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
9448 + /* a block either controls scope or breaks (never both) */
9449 + lua_assert(!bl->isbreakable || !bl->upval);
9450 + lua_assert(bl->nactvar == fs->nactvar);
9451 + fs->freereg = fs->nactvar; /* free registers */
9452 + luaK_patchtohere(fs, bl->breaklist);
9456 +static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
9457 + FuncState *fs = ls->fs;
9459 + int oldsize = f->sizep;
9461 + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
9462 + MAXARG_Bx, "constant table overflow");
9463 + while (oldsize < f->sizep) f->p[oldsize++] = NULL;
9464 + f->p[fs->np++] = func->f;
9465 + luaC_objbarrier(ls->L, f, func->f);
9466 + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
9467 + for (i=0; i<func->f->nups; i++) {
9468 + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
9469 + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
9474 +static void open_func (LexState *ls, FuncState *fs) {
9475 + lua_State *L = ls->L;
9476 + Proto *f = luaF_newproto(L);
9478 + fs->prev = ls->fs; /* linked list of funcstates */
9483 + fs->lasttarget = -1;
9484 + fs->jpc = NO_JUMP;
9491 + f->source = ls->source;
9492 + f->maxstacksize = 2; /* registers 0/1 are always valid */
9493 + fs->h = luaH_new(L, 0, 0);
9494 + /* anchor table of constants and prototype (to avoid being collected) */
9495 + sethvalue2s(L, L->top, fs->h);
9497 + setptvalue2s(L, L->top, f);
9502 +static void close_func (LexState *ls) {
9503 + lua_State *L = ls->L;
9504 + FuncState *fs = ls->fs;
9506 + removevars(ls, 0);
9507 + luaK_ret(fs, 0, 0); /* final return */
9508 + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
9509 + f->sizecode = fs->pc;
9510 + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
9511 + f->sizelineinfo = fs->pc;
9512 + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
9513 + f->sizek = fs->nk;
9514 + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
9515 + f->sizep = fs->np;
9516 + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
9517 + f->sizelocvars = fs->nlocvars;
9518 + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
9519 + f->sizeupvalues = f->nups;
9520 + lua_assert(luaG_checkcode(f));
9521 + lua_assert(fs->bl == NULL);
9522 + ls->fs = fs->prev;
9523 + L->top -= 2; /* remove table and prototype from the stack */
9524 + /* last token read was anchored in defunct function; must reanchor it */
9525 + if (fs) anchor_token(ls);
9529 +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
9530 + struct LexState lexstate;
9531 + struct FuncState funcstate;
9532 + lexstate.buff = buff;
9533 + luaX_setinput(L, &lexstate, z, luaS_new(L, name));
9534 + open_func(&lexstate, &funcstate);
9535 + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
9536 + luaX_next(&lexstate); /* read first token */
9538 + check(&lexstate, TK_EOS);
9539 + close_func(&lexstate);
9540 + lua_assert(funcstate.prev == NULL);
9541 + lua_assert(funcstate.f->nups == 0);
9542 + lua_assert(lexstate.fs == NULL);
9543 + return funcstate.f;
9548 +/*============================================================*/
9549 +/* GRAMMAR RULES */
9550 +/*============================================================*/
9553 +static void field (LexState *ls, expdesc *v) {
9554 + /* field -> ['.' | ':'] NAME */
9555 + FuncState *fs = ls->fs;
9557 + luaK_exp2anyreg(fs, v);
9558 + luaX_next(ls); /* skip the dot or colon */
9559 + checkname(ls, &key);
9560 + luaK_indexed(fs, v, &key);
9564 +static void yindex (LexState *ls, expdesc *v) {
9565 + /* index -> '[' expr ']' */
9566 + luaX_next(ls); /* skip the '[' */
9568 + luaK_exp2val(ls->fs, v);
9569 + checknext(ls, ']');
9574 +** {======================================================================
9575 +** Rules for Constructors
9576 +** =======================================================================
9580 +struct ConsControl {
9581 + expdesc v; /* last list item read */
9582 + expdesc *t; /* table descriptor */
9583 + int nh; /* total number of `record' elements */
9584 + int na; /* total number of array elements */
9585 + int tostore; /* number of array elements pending to be stored */
9589 +static void recfield (LexState *ls, struct ConsControl *cc) {
9590 + /* recfield -> (NAME | `['exp1`]') = exp1 */
9591 + FuncState *fs = ls->fs;
9592 + int reg = ls->fs->freereg;
9595 + if (ls->t.token == TK_NAME) {
9596 + luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
9597 + checkname(ls, &key);
9599 + else /* ls->t.token == '[' */
9602 + checknext(ls, '=');
9603 + rkkey = luaK_exp2RK(fs, &key);
9605 + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
9606 + fs->freereg = reg; /* free registers */
9610 +static void closelistfield (FuncState *fs, struct ConsControl *cc) {
9611 + if (cc->v.k == VVOID) return; /* there is no list item */
9612 + luaK_exp2nextreg(fs, &cc->v);
9614 + if (cc->tostore == LFIELDS_PER_FLUSH) {
9615 + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
9616 + cc->tostore = 0; /* no more items pending */
9621 +static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
9622 + if (cc->tostore == 0) return;
9623 + if (hasmultret(cc->v.k)) {
9624 + luaK_setmultret(fs, &cc->v);
9625 + luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
9626 + cc->na--; /* do not count last expression (unknown number of elements) */
9629 + if (cc->v.k != VVOID)
9630 + luaK_exp2nextreg(fs, &cc->v);
9631 + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
9636 +static void listfield (LexState *ls, struct ConsControl *cc) {
9638 + luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
9644 +static void constructor (LexState *ls, expdesc *t) {
9645 + /* constructor -> ?? */
9646 + FuncState *fs = ls->fs;
9647 + int line = ls->linenumber;
9648 + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
9649 + struct ConsControl cc;
9650 + cc.na = cc.nh = cc.tostore = 0;
9652 + init_exp(t, VRELOCABLE, pc);
9653 + init_exp(&cc.v, VVOID, 0); /* no value (yet) */
9654 + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
9655 + checknext(ls, '{');
9657 + lua_assert(cc.v.k == VVOID || cc.tostore > 0);
9658 + if (ls->t.token == '}') break;
9659 + closelistfield(fs, &cc);
9660 + switch(ls->t.token) {
9661 + case TK_NAME: { /* may be listfields or recfields */
9662 + luaX_lookahead(ls);
9663 + if (ls->lookahead.token != '=') /* expression? */
9664 + listfield(ls, &cc);
9666 + recfield(ls, &cc);
9669 + case '[': { /* constructor_item -> recfield */
9670 + recfield(ls, &cc);
9673 + default: { /* constructor_part -> listfield */
9674 + listfield(ls, &cc);
9678 + } while (testnext(ls, ',') || testnext(ls, ';'));
9679 + check_match(ls, '}', '{', line);
9680 + lastlistfield(fs, &cc);
9681 + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
9682 + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
9685 +/* }====================================================================== */
9689 +static void parlist (LexState *ls) {
9690 + /* parlist -> [ param { `,' param } ] */
9691 + FuncState *fs = ls->fs;
9695 + if (ls->t.token != ')') { /* is `parlist' not empty? */
9697 + switch (ls->t.token) {
9698 + case TK_NAME: { /* param -> NAME */
9699 + new_localvar(ls, str_checkname(ls), nparams++);
9702 + case TK_DOTS: { /* param -> `...' */
9704 +#if defined(LUA_COMPAT_VARARG)
9705 + /* use `arg' as default name */
9706 + new_localvarliteral(ls, "arg", nparams++);
9707 + f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
9709 + f->is_vararg |= VARARG_ISVARARG;
9712 + default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
9714 + } while (!f->is_vararg && testnext(ls, ','));
9716 + adjustlocalvars(ls, nparams);
9717 + f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
9718 + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
9722 +static void body (LexState *ls, expdesc *e, int needself, int line) {
9723 + /* body -> `(' parlist `)' chunk END */
9725 + open_func(ls, &new_fs);
9726 + new_fs.f->linedefined = line;
9727 + checknext(ls, '(');
9729 + new_localvarliteral(ls, "self", 0);
9730 + adjustlocalvars(ls, 1);
9733 + checknext(ls, ')');
9735 + new_fs.f->lastlinedefined = ls->linenumber;
9736 + check_match(ls, TK_END, TK_FUNCTION, line);
9738 + pushclosure(ls, &new_fs, e);
9742 +static int explist1 (LexState *ls, expdesc *v) {
9743 + /* explist1 -> expr { `,' expr } */
9744 + int n = 1; /* at least one expression */
9746 + while (testnext(ls, ',')) {
9747 + luaK_exp2nextreg(ls->fs, v);
9755 +static void funcargs (LexState *ls, expdesc *f) {
9756 + FuncState *fs = ls->fs;
9758 + int base, nparams;
9759 + int line = ls->linenumber;
9760 + switch (ls->t.token) {
9761 + case '(': { /* funcargs -> `(' [ explist1 ] `)' */
9762 + if (line != ls->lastline)
9763 + luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
9765 + if (ls->t.token == ')') /* arg list is empty? */
9768 + explist1(ls, &args);
9769 + luaK_setmultret(fs, &args);
9771 + check_match(ls, ')', '(', line);
9774 + case '{': { /* funcargs -> constructor */
9775 + constructor(ls, &args);
9778 + case TK_STRING: { /* funcargs -> STRING */
9779 + codestring(ls, &args, ls->t.seminfo.ts);
9780 + luaX_next(ls); /* must use `seminfo' before `next' */
9784 + luaX_syntaxerror(ls, "function arguments expected");
9788 + lua_assert(f->k == VNONRELOC);
9789 + base = f->u.s.info; /* base register for call */
9790 + if (hasmultret(args.k))
9791 + nparams = LUA_MULTRET; /* open call */
9793 + if (args.k != VVOID)
9794 + luaK_exp2nextreg(fs, &args); /* close last argument */
9795 + nparams = fs->freereg - (base+1);
9797 + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
9798 + luaK_fixline(fs, line);
9799 + fs->freereg = base+1; /* call remove function and arguments and leaves
9800 + (unless changed) one result */
9807 +** {======================================================================
9808 +** Expression parsing
9809 +** =======================================================================
9813 +static void prefixexp (LexState *ls, expdesc *v) {
9814 + /* prefixexp -> NAME | '(' expr ')' */
9815 + switch (ls->t.token) {
9817 + int line = ls->linenumber;
9820 + check_match(ls, ')', '(', line);
9821 + luaK_dischargevars(ls->fs, v);
9829 + luaX_syntaxerror(ls, "unexpected symbol");
9836 +static void primaryexp (LexState *ls, expdesc *v) {
9838 + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
9839 + FuncState *fs = ls->fs;
9842 + switch (ls->t.token) {
9843 + case '.': { /* field */
9847 + case '[': { /* `[' exp1 `]' */
9849 + luaK_exp2anyreg(fs, v);
9851 + luaK_indexed(fs, v, &key);
9854 + case ':': { /* `:' NAME funcargs */
9857 + checkname(ls, &key);
9858 + luaK_self(fs, v, &key);
9862 + case '(': case TK_STRING: case '{': { /* funcargs */
9863 + luaK_exp2nextreg(fs, v);
9873 +static void simpleexp (LexState *ls, expdesc *v) {
9874 + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
9875 + constructor | FUNCTION body | primaryexp */
9876 + switch (ls->t.token) {
9878 + init_exp(v, VKNUM, 0);
9879 + v->u.nval = ls->t.seminfo.r;
9883 + codestring(ls, v, ls->t.seminfo.ts);
9887 + init_exp(v, VNIL, 0);
9891 + init_exp(v, VTRUE, 0);
9895 + init_exp(v, VFALSE, 0);
9898 + case TK_DOTS: { /* vararg */
9899 + FuncState *fs = ls->fs;
9900 + check_condition(ls, fs->f->is_vararg,
9901 + "cannot use " LUA_QL("...") " outside a vararg function");
9902 + fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
9903 + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
9906 + case '{': { /* constructor */
9907 + constructor(ls, v);
9910 + case TK_FUNCTION: {
9912 + body(ls, v, 0, ls->linenumber);
9916 + primaryexp(ls, v);
9924 +static UnOpr getunopr (int op) {
9926 + case TK_NOT: return OPR_NOT;
9927 + case '-': return OPR_MINUS;
9928 + case '#': return OPR_LEN;
9929 + default: return OPR_NOUNOPR;
9934 +static BinOpr getbinopr (int op) {
9936 + case '+': return OPR_ADD;
9937 + case '-': return OPR_SUB;
9938 + case '*': return OPR_MUL;
9939 + case '/': return OPR_DIV;
9940 + case '%': return OPR_MOD;
9941 + case '^': return OPR_POW;
9942 + case TK_CONCAT: return OPR_CONCAT;
9943 + case TK_NE: return OPR_NE;
9944 + case TK_EQ: return OPR_EQ;
9945 + case '<': return OPR_LT;
9946 + case TK_LE: return OPR_LE;
9947 + case '>': return OPR_GT;
9948 + case TK_GE: return OPR_GE;
9949 + case TK_AND: return OPR_AND;
9950 + case TK_OR: return OPR_OR;
9951 + default: return OPR_NOBINOPR;
9956 +static const struct {
9957 + lu_byte left; /* left priority for each binary operator */
9958 + lu_byte right; /* right priority */
9959 +} priority[] = { /* ORDER OPR */
9960 + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
9961 + {10, 9}, {5, 4}, /* power and concat (right associative) */
9962 + {3, 3}, {3, 3}, /* equality and inequality */
9963 + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
9964 + {2, 2}, {1, 1} /* logical (and/or) */
9967 +#define UNARY_PRIORITY 8 /* priority for unary operators */
9971 +** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
9972 +** where `binop' is any binary operator with a priority higher than `limit'
9974 +static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
9978 + uop = getunopr(ls->t.token);
9979 + if (uop != OPR_NOUNOPR) {
9981 + subexpr(ls, v, UNARY_PRIORITY);
9982 + luaK_prefix(ls->fs, uop, v);
9984 + else simpleexp(ls, v);
9985 + /* expand while operators have priorities higher than `limit' */
9986 + op = getbinopr(ls->t.token);
9987 + while (op != OPR_NOBINOPR && priority[op].left > limit) {
9991 + luaK_infix(ls->fs, op, v);
9992 + /* read sub-expression with higher priority */
9993 + nextop = subexpr(ls, &v2, priority[op].right);
9994 + luaK_posfix(ls->fs, op, v, &v2);
9998 + return op; /* return first untreated operator */
10002 +static void expr (LexState *ls, expdesc *v) {
10003 + subexpr(ls, v, 0);
10006 +/* }==================================================================== */
10011 +** {======================================================================
10012 +** Rules for Statements
10013 +** =======================================================================
10017 +static int block_follow (int token) {
10019 + case TK_ELSE: case TK_ELSEIF: case TK_END:
10020 + case TK_UNTIL: case TK_EOS:
10022 + default: return 0;
10027 +static void block (LexState *ls) {
10028 + /* block -> chunk */
10029 + FuncState *fs = ls->fs;
10031 + enterblock(fs, &bl, 0);
10033 + lua_assert(bl.breaklist == NO_JUMP);
10039 +** structure to chain all variables in the left-hand side of an
10042 +struct LHS_assign {
10043 + struct LHS_assign *prev;
10044 + expdesc v; /* variable (global, local, upvalue, or indexed) */
10049 +** check whether, in an assignment to a local variable, the local variable
10050 +** is needed in a previous assignment (to a table). If so, save original
10051 +** local value in a safe place and use this safe copy in the previous
10054 +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
10055 + FuncState *fs = ls->fs;
10056 + int extra = fs->freereg; /* eventual position to save local variable */
10057 + int conflict = 0;
10058 + for (; lh; lh = lh->prev) {
10059 + if (lh->v.k == VINDEXED) {
10060 + if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
10062 + lh->v.u.s.info = extra; /* previous assignment will use safe copy */
10064 + if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
10066 + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
10071 + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
10072 + luaK_reserveregs(fs, 1);
10077 +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
10079 + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
10081 + if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
10082 + struct LHS_assign nv;
10084 + primaryexp(ls, &nv.v);
10085 + if (nv.v.k == VLOCAL)
10086 + check_conflict(ls, lh, &nv.v);
10087 + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
10088 + "variables in assignment");
10089 + assignment(ls, &nv, nvars+1);
10091 + else { /* assignment -> `=' explist1 */
10093 + checknext(ls, '=');
10094 + nexps = explist1(ls, &e);
10095 + if (nexps != nvars) {
10096 + adjust_assign(ls, nvars, nexps, &e);
10097 + if (nexps > nvars)
10098 + ls->fs->freereg -= nexps - nvars; /* remove extra values */
10101 + luaK_setoneret(ls->fs, &e); /* close last expression */
10102 + luaK_storevar(ls->fs, &lh->v, &e);
10103 + return; /* avoid default */
10106 + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
10107 + luaK_storevar(ls->fs, &lh->v, &e);
10111 +static int cond (LexState *ls) {
10112 + /* cond -> exp */
10114 + expr(ls, &v); /* read condition */
10115 + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
10116 + luaK_goiftrue(ls->fs, &v);
10121 +static void breakstat (LexState *ls) {
10122 + FuncState *fs = ls->fs;
10123 + BlockCnt *bl = fs->bl;
10125 + while (bl && !bl->isbreakable) {
10126 + upval |= bl->upval;
10127 + bl = bl->previous;
10130 + luaX_syntaxerror(ls, "no loop to break");
10132 + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
10133 + luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
10137 +static void whilestat (LexState *ls, int line) {
10138 + /* whilestat -> WHILE cond DO block END */
10139 + FuncState *fs = ls->fs;
10143 + luaX_next(ls); /* skip WHILE */
10144 + whileinit = luaK_getlabel(fs);
10145 + condexit = cond(ls);
10146 + enterblock(fs, &bl, 1);
10147 + checknext(ls, TK_DO);
10149 + luaK_patchlist(fs, luaK_jump(fs), whileinit);
10150 + check_match(ls, TK_END, TK_WHILE, line);
10152 + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
10156 +static void repeatstat (LexState *ls, int line) {
10157 + /* repeatstat -> REPEAT block UNTIL cond */
10159 + FuncState *fs = ls->fs;
10160 + int repeat_init = luaK_getlabel(fs);
10161 + BlockCnt bl1, bl2;
10162 + enterblock(fs, &bl1, 1); /* loop block */
10163 + enterblock(fs, &bl2, 0); /* scope block */
10164 + luaX_next(ls); /* skip REPEAT */
10166 + check_match(ls, TK_UNTIL, TK_REPEAT, line);
10167 + condexit = cond(ls); /* read condition (inside scope block) */
10168 + if (!bl2.upval) { /* no upvalues? */
10169 + leaveblock(fs); /* finish scope */
10170 + luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
10172 + else { /* complete semantics when there are upvalues */
10173 + breakstat(ls); /* if condition then break */
10174 + luaK_patchtohere(ls->fs, condexit); /* else... */
10175 + leaveblock(fs); /* finish scope... */
10176 + luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
10178 + leaveblock(fs); /* finish loop */
10182 +static int exp1 (LexState *ls) {
10187 + luaK_exp2nextreg(ls->fs, &e);
10192 +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
10193 + /* forbody -> DO block */
10195 + FuncState *fs = ls->fs;
10196 + int prep, endfor;
10197 + adjustlocalvars(ls, 3); /* control variables */
10198 + checknext(ls, TK_DO);
10199 + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
10200 + enterblock(fs, &bl, 0); /* scope for declared variables */
10201 + adjustlocalvars(ls, nvars);
10202 + luaK_reserveregs(fs, nvars);
10204 + leaveblock(fs); /* end of scope for declared variables */
10205 + luaK_patchtohere(fs, prep);
10206 + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
10207 + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
10208 + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
10209 + luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
10213 +static void fornum (LexState *ls, TString *varname, int line) {
10214 + /* fornum -> NAME = exp1,exp1[,exp1] forbody */
10215 + FuncState *fs = ls->fs;
10216 + int base = fs->freereg;
10217 + new_localvarliteral(ls, "(for index)", 0);
10218 + new_localvarliteral(ls, "(for limit)", 1);
10219 + new_localvarliteral(ls, "(for step)", 2);
10220 + new_localvar(ls, varname, 3);
10221 + checknext(ls, '=');
10222 + exp1(ls); /* initial value */
10223 + checknext(ls, ',');
10224 + exp1(ls); /* limit */
10225 + if (testnext(ls, ','))
10226 + exp1(ls); /* optional step */
10227 + else { /* default step = 1 */
10228 + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
10229 + luaK_reserveregs(fs, 1);
10231 + forbody(ls, base, line, 1, 1);
10235 +static void forlist (LexState *ls, TString *indexname) {
10236 + /* forlist -> NAME {,NAME} IN explist1 forbody */
10237 + FuncState *fs = ls->fs;
10241 + int base = fs->freereg;
10242 + /* create control variables */
10243 + new_localvarliteral(ls, "(for generator)", nvars++);
10244 + new_localvarliteral(ls, "(for state)", nvars++);
10245 + new_localvarliteral(ls, "(for control)", nvars++);
10246 + /* create declared variables */
10247 + new_localvar(ls, indexname, nvars++);
10248 + while (testnext(ls, ','))
10249 + new_localvar(ls, str_checkname(ls), nvars++);
10250 + checknext(ls, TK_IN);
10251 + line = ls->linenumber;
10252 + adjust_assign(ls, 3, explist1(ls, &e), &e);
10253 + luaK_checkstack(fs, 3); /* extra space to call generator */
10254 + forbody(ls, base, line, nvars - 3, 0);
10258 +static void forstat (LexState *ls, int line) {
10259 + /* forstat -> FOR (fornum | forlist) END */
10260 + FuncState *fs = ls->fs;
10261 + TString *varname;
10263 + enterblock(fs, &bl, 1); /* scope for loop and control variables */
10264 + luaX_next(ls); /* skip `for' */
10265 + varname = str_checkname(ls); /* first variable name */
10266 + switch (ls->t.token) {
10267 + case '=': fornum(ls, varname, line); break;
10268 + case ',': case TK_IN: forlist(ls, varname); break;
10269 + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
10271 + check_match(ls, TK_END, TK_FOR, line);
10272 + leaveblock(fs); /* loop scope (`break' jumps to this point) */
10276 +static int test_then_block (LexState *ls) {
10277 + /* test_then_block -> [IF | ELSEIF] cond THEN block */
10279 + luaX_next(ls); /* skip IF or ELSEIF */
10280 + condexit = cond(ls);
10281 + checknext(ls, TK_THEN);
10282 + block(ls); /* `then' part */
10287 +static void ifstat (LexState *ls, int line) {
10288 + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
10289 + FuncState *fs = ls->fs;
10291 + int escapelist = NO_JUMP;
10292 + flist = test_then_block(ls); /* IF cond THEN block */
10293 + while (ls->t.token == TK_ELSEIF) {
10294 + luaK_concat(fs, &escapelist, luaK_jump(fs));
10295 + luaK_patchtohere(fs, flist);
10296 + flist = test_then_block(ls); /* ELSEIF cond THEN block */
10298 + if (ls->t.token == TK_ELSE) {
10299 + luaK_concat(fs, &escapelist, luaK_jump(fs));
10300 + luaK_patchtohere(fs, flist);
10301 + luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
10302 + block(ls); /* `else' part */
10305 + luaK_concat(fs, &escapelist, flist);
10306 + luaK_patchtohere(fs, escapelist);
10307 + check_match(ls, TK_END, TK_IF, line);
10311 +static void localfunc (LexState *ls) {
10313 + FuncState *fs = ls->fs;
10314 + new_localvar(ls, str_checkname(ls), 0);
10315 + init_exp(&v, VLOCAL, fs->freereg);
10316 + luaK_reserveregs(fs, 1);
10317 + adjustlocalvars(ls, 1);
10318 + body(ls, &b, 0, ls->linenumber);
10319 + luaK_storevar(fs, &v, &b);
10320 + /* debug information will only see the variable after this point! */
10321 + getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
10325 +static void localstat (LexState *ls) {
10326 + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
10331 + new_localvar(ls, str_checkname(ls), nvars++);
10332 + } while (testnext(ls, ','));
10333 + if (testnext(ls, '='))
10334 + nexps = explist1(ls, &e);
10339 + adjust_assign(ls, nvars, nexps, &e);
10340 + adjustlocalvars(ls, nvars);
10344 +static int funcname (LexState *ls, expdesc *v) {
10345 + /* funcname -> NAME {field} [`:' NAME] */
10346 + int needself = 0;
10347 + singlevar(ls, v);
10348 + while (ls->t.token == '.')
10350 + if (ls->t.token == ':') {
10358 +static void funcstat (LexState *ls, int line) {
10359 + /* funcstat -> FUNCTION funcname body */
10362 + luaX_next(ls); /* skip FUNCTION */
10363 + needself = funcname(ls, &v);
10364 + body(ls, &b, needself, line);
10365 + luaK_storevar(ls->fs, &v, &b);
10366 + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
10370 +static void exprstat (LexState *ls) {
10371 + /* stat -> func | assignment */
10372 + FuncState *fs = ls->fs;
10373 + struct LHS_assign v;
10374 + primaryexp(ls, &v.v);
10375 + if (v.v.k == VCALL) /* stat -> func */
10376 + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
10377 + else { /* stat -> assignment */
10379 + assignment(ls, &v, 1);
10384 +static void retstat (LexState *ls) {
10385 + /* stat -> RETURN explist */
10386 + FuncState *fs = ls->fs;
10388 + int first, nret; /* registers with returned values */
10389 + luaX_next(ls); /* skip RETURN */
10390 + if (block_follow(ls->t.token) || ls->t.token == ';')
10391 + first = nret = 0; /* return no values */
10393 + nret = explist1(ls, &e); /* optional return values */
10394 + if (hasmultret(e.k)) {
10395 + luaK_setmultret(fs, &e);
10396 + if (e.k == VCALL && nret == 1) { /* tail call? */
10397 + SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
10398 + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
10400 + first = fs->nactvar;
10401 + nret = LUA_MULTRET; /* return all values */
10404 + if (nret == 1) /* only one single value? */
10405 + first = luaK_exp2anyreg(fs, &e);
10407 + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
10408 + first = fs->nactvar; /* return all `active' values */
10409 + lua_assert(nret == fs->freereg - first);
10413 + luaK_ret(fs, first, nret);
10417 +static int statement (LexState *ls) {
10418 + int line = ls->linenumber; /* may be needed for error messages */
10419 + switch (ls->t.token) {
10420 + case TK_IF: { /* stat -> ifstat */
10421 + ifstat(ls, line);
10424 + case TK_WHILE: { /* stat -> whilestat */
10425 + whilestat(ls, line);
10428 + case TK_DO: { /* stat -> DO block END */
10429 + luaX_next(ls); /* skip DO */
10431 + check_match(ls, TK_END, TK_DO, line);
10434 + case TK_FOR: { /* stat -> forstat */
10435 + forstat(ls, line);
10438 + case TK_REPEAT: { /* stat -> repeatstat */
10439 + repeatstat(ls, line);
10442 + case TK_FUNCTION: {
10443 + funcstat(ls, line); /* stat -> funcstat */
10446 + case TK_LOCAL: { /* stat -> localstat */
10447 + luaX_next(ls); /* skip LOCAL */
10448 + if (testnext(ls, TK_FUNCTION)) /* local function? */
10454 + case TK_RETURN: { /* stat -> retstat */
10456 + return 1; /* must be last statement */
10458 + case TK_BREAK: { /* stat -> breakstat */
10459 + luaX_next(ls); /* skip BREAK */
10461 + return 1; /* must be last statement */
10465 + return 0; /* to avoid warnings */
10471 +static void chunk (LexState *ls) {
10472 + /* chunk -> { stat [`;'] } */
10475 + while (!islast && !block_follow(ls->t.token)) {
10476 + islast = statement(ls);
10477 + testnext(ls, ';');
10478 + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
10479 + ls->fs->freereg >= ls->fs->nactvar);
10480 + ls->fs->freereg = ls->fs->nactvar; /* free registers */
10485 +/* }====================================================================== */
10487 +++ b/extensions/LUA/lua/lparser.h
10490 +** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
10492 +** See Copyright Notice in lua.h
10498 +#include "llimits.h"
10499 +#include "lobject.h"
10504 +** Expression descriptor
10508 + VVOID, /* no value */
10512 + VK, /* info = index of constant in `k' */
10513 + VKNUM, /* nval = numerical value */
10514 + VLOCAL, /* info = local register */
10515 + VUPVAL, /* info = index of upvalue in `upvalues' */
10516 + VGLOBAL, /* info = index of table; aux = index of global name in `k' */
10517 + VINDEXED, /* info = table register; aux = index register (or `k') */
10518 + VJMP, /* info = instruction pc */
10519 + VRELOCABLE, /* info = instruction pc */
10520 + VNONRELOC, /* info = result register */
10521 + VCALL, /* info = instruction pc */
10522 + VVARARG /* info = instruction pc */
10525 +typedef struct expdesc {
10528 + struct { int info, aux; } s;
10531 + int t; /* patch list of `exit when true' */
10532 + int f; /* patch list of `exit when false' */
10536 +typedef struct upvaldesc {
10542 +struct BlockCnt; /* defined in lparser.c */
10545 +/* state needed to generate code for a given function */
10546 +typedef struct FuncState {
10547 + Proto *f; /* current function header */
10548 + Table *h; /* table to find (and reuse) elements in `k' */
10549 + struct FuncState *prev; /* enclosing function */
10550 + struct LexState *ls; /* lexical state */
10551 + struct lua_State *L; /* copy of the Lua state */
10552 + struct BlockCnt *bl; /* chain of current blocks */
10553 + int pc; /* next position to code (equivalent to `ncode') */
10554 + int lasttarget; /* `pc' of last `jump target' */
10555 + int jpc; /* list of pending jumps to `pc' */
10556 + int freereg; /* first free register */
10557 + int nk; /* number of elements in `k' */
10558 + int np; /* number of elements in `p' */
10559 + short nlocvars; /* number of elements in `locvars' */
10560 + lu_byte nactvar; /* number of active local variables */
10561 + upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
10562 + unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
10566 +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
10567 + const char *name);
10572 +++ b/extensions/LUA/lua/lstate.c
10575 +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
10577 +** See Copyright Notice in lua.h
10581 +#include <stddef.h>
10588 +#include "ldebug.h"
10590 +#include "lfunc.h"
10594 +#include "lstate.h"
10595 +#include "lstring.h"
10596 +#include "ltable.h"
10600 +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
10601 +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
10602 +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
10606 +** Main thread combines a thread state and the global state
10608 +typedef struct LG {
10615 +static void stack_init (lua_State *L1, lua_State *L) {
10616 + /* initialize CallInfo array */
10617 + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
10618 + L1->ci = L1->base_ci;
10619 + L1->size_ci = BASIC_CI_SIZE;
10620 + L1->end_ci = L1->base_ci + L1->size_ci - 1;
10621 + /* initialize stack array */
10622 + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
10623 + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
10624 + L1->top = L1->stack;
10625 + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
10626 + /* initialize first ci */
10627 + L1->ci->func = L1->top;
10628 + setnilvalue(L1->top++); /* `function' entry for this `ci' */
10629 + L1->base = L1->ci->base = L1->top;
10630 + L1->ci->top = L1->top + LUA_MINSTACK;
10634 +static void freestack (lua_State *L, lua_State *L1) {
10635 + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
10636 + luaM_freearray(L, L1->stack, L1->stacksize, TValue);
10641 +** open parts that may cause memory-allocation errors
10643 +static void f_luaopen (lua_State *L, void *ud) {
10644 + global_State *g = G(L);
10646 + stack_init(L, L); /* init stack */
10647 + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
10648 + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
10649 + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
10652 + luaS_fix(luaS_newliteral(L, MEMERRMSG));
10653 + g->GCthreshold = 4*g->totalbytes;
10657 +static void preinit_state (lua_State *L, global_State *g) {
10660 + L->stacksize = 0;
10661 + L->errorJmp = NULL;
10664 + L->basehookcount = 0;
10665 + L->allowhook = 1;
10666 + resethookcount(L);
10667 + L->openupval = NULL;
10669 + L->nCcalls = L->baseCcalls = 0;
10671 + L->base_ci = L->ci = NULL;
10672 + L->savedpc = NULL;
10674 + setnilvalue(gt(L));
10678 +static void close_state (lua_State *L) {
10679 + global_State *g = G(L);
10680 + luaF_close(L, L->stack); /* close all upvalues for this thread */
10681 + luaC_freeall(L); /* collect all objects */
10682 + lua_assert(g->rootgc == obj2gco(L));
10683 + lua_assert(g->strt.nuse == 0);
10684 + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
10685 + luaZ_freebuffer(L, &g->buff);
10687 + lua_assert(g->totalbytes == sizeof(LG));
10688 + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
10692 +lua_State *luaE_newthread (lua_State *L) {
10693 + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
10694 + luaC_link(L, obj2gco(L1), LUA_TTHREAD);
10695 + preinit_state(L1, G(L));
10696 + stack_init(L1, L); /* init stack */
10697 + setobj2n(L, gt(L1), gt(L)); /* share table of globals */
10698 + L1->hookmask = L->hookmask;
10699 + L1->basehookcount = L->basehookcount;
10700 + L1->hook = L->hook;
10701 + resethookcount(L1);
10702 + lua_assert(iswhite(obj2gco(L1)));
10707 +void luaE_freethread (lua_State *L, lua_State *L1) {
10708 + luaF_close(L1, L1->stack); /* close all upvalues for this thread */
10709 + lua_assert(L1->openupval == NULL);
10710 + luai_userstatefree(L1);
10711 + freestack(L, L1);
10712 + luaM_freemem(L, fromstate(L1), state_size(lua_State));
10716 +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
10720 + void *l = (*f)(ud, NULL, 0, state_size(LG));
10721 + if (l == NULL) return NULL;
10723 + g = &((LG *)L)->g;
10725 + L->tt = LUA_TTHREAD;
10726 + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
10727 + L->marked = luaC_white(g);
10728 + set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
10729 + preinit_state(L, g);
10732 + g->mainthread = L;
10733 + g->uvhead.u.l.prev = &g->uvhead;
10734 + g->uvhead.u.l.next = &g->uvhead;
10735 + g->GCthreshold = 0; /* mark it as unfinished state */
10736 + g->strt.size = 0;
10737 + g->strt.nuse = 0;
10738 + g->strt.hash = NULL;
10739 + setnilvalue(registry(L));
10740 + luaZ_initbuffer(L, &g->buff);
10742 + g->gcstate = GCSpause;
10743 + g->rootgc = obj2gco(L);
10744 + g->sweepstrgc = 0;
10745 + g->sweepgc = &g->rootgc;
10747 + g->grayagain = NULL;
10749 + g->tmudata = NULL;
10750 + g->totalbytes = sizeof(LG);
10751 + g->gcpause = LUAI_GCPAUSE;
10752 + g->gcstepmul = LUAI_GCMUL;
10754 + for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
10755 + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
10756 + /* memory allocation error: free partial state */
10761 + luai_userstateopen(L);
10766 +static void callallgcTM (lua_State *L, void *ud) {
10768 + luaC_callGCTM(L); /* call GC metamethods for all udata */
10772 +LUA_API void lua_close (lua_State *L) {
10773 + L = G(L)->mainthread; /* only the main thread can be closed */
10775 + luaF_close(L, L->stack); /* close all upvalues for this thread */
10776 + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
10777 + L->errfunc = 0; /* no error function during GC metamethods */
10778 + do { /* repeat until no more errors */
10779 + L->ci = L->base_ci;
10780 + L->base = L->top = L->ci->base;
10781 + L->nCcalls = L->baseCcalls = 0;
10782 + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
10783 + lua_assert(G(L)->tmudata == NULL);
10784 + luai_userstateclose(L);
10789 +++ b/extensions/LUA/lua/lstate.h
10792 +** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
10794 +** See Copyright Notice in lua.h
10802 +#include "lobject.h"
10808 +struct lua_longjmp; /* defined in ldo.c */
10811 +/* table of globals */
10812 +#define gt(L) (&L->l_gt)
10815 +#define registry(L) (&G(L)->l_registry)
10818 +/* extra stack space to handle TM calls and some other extras */
10819 +#define EXTRA_STACK 5
10822 +#define BASIC_CI_SIZE 8
10824 +#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
10828 +typedef struct stringtable {
10830 + lu_int32 nuse; /* number of elements */
10836 +** informations about a call
10838 +typedef struct CallInfo {
10839 + StkId base; /* base for this function */
10840 + StkId func; /* function index in the stack */
10841 + StkId top; /* top for this function */
10842 + const Instruction *savedpc;
10843 + int nresults; /* expected number of results from this function */
10844 + int tailcalls; /* number of tail calls lost under this entry */
10849 +#define curr_func(L) (clvalue(L->ci->func))
10850 +#define ci_func(ci) (clvalue((ci)->func))
10851 +#define f_isLua(ci) (!ci_func(ci)->c.isC)
10852 +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
10856 +** `global state', shared by all threads of this state
10858 +typedef struct global_State {
10859 + stringtable strt; /* hash table for strings */
10860 + lua_Alloc frealloc; /* function to reallocate memory */
10861 + void *ud; /* auxiliary data to `frealloc' */
10862 + lu_byte currentwhite;
10863 + lu_byte gcstate; /* state of garbage collector */
10864 + int sweepstrgc; /* position of sweep in `strt' */
10865 + GCObject *rootgc; /* list of all collectable objects */
10866 + GCObject **sweepgc; /* position of sweep in `rootgc' */
10867 + GCObject *gray; /* list of gray objects */
10868 + GCObject *grayagain; /* list of objects to be traversed atomically */
10869 + GCObject *weak; /* list of weak tables (to be cleared) */
10870 + GCObject *tmudata; /* last element of list of userdata to be GC */
10871 + Mbuffer buff; /* temporary buffer for string concatentation */
10872 + lu_mem GCthreshold;
10873 + lu_mem totalbytes; /* number of bytes currently allocated */
10874 + lu_mem estimate; /* an estimate of number of bytes actually in use */
10875 + lu_mem gcdept; /* how much GC is `behind schedule' */
10876 + int gcpause; /* size of pause between successive GCs */
10877 + int gcstepmul; /* GC `granularity' */
10878 + lua_CFunction panic; /* to be called in unprotected errors */
10879 + TValue l_registry;
10880 + struct lua_State *mainthread;
10881 + UpVal uvhead; /* head of double-linked list of all open upvalues */
10882 + struct Table *mt[NUM_TAGS]; /* metatables for basic types */
10883 + TString *tmname[TM_N]; /* array with tag-method names */
10888 +** `per thread' state
10890 +struct lua_State {
10893 + StkId top; /* first free slot in the stack */
10894 + StkId base; /* base of current function */
10895 + global_State *l_G;
10896 + CallInfo *ci; /* call info for current function */
10897 + const Instruction *savedpc; /* `savedpc' of current function */
10898 + StkId stack_last; /* last free slot in the stack */
10899 + StkId stack; /* stack base */
10900 + CallInfo *end_ci; /* points after end of ci array*/
10901 + CallInfo *base_ci; /* array of CallInfo's */
10903 + int size_ci; /* size of array `base_ci' */
10904 + unsigned short nCcalls; /* number of nested C calls */
10905 + unsigned short baseCcalls; /* nested C calls when resuming coroutine */
10906 + lu_byte hookmask;
10907 + lu_byte allowhook;
10908 + int basehookcount;
10911 + TValue l_gt; /* table of globals */
10912 + TValue env; /* temporary place for environments */
10913 + GCObject *openupval; /* list of open upvalues in this stack */
10914 + GCObject *gclist;
10915 + struct lua_longjmp *errorJmp; /* current error recover point */
10916 + ptrdiff_t errfunc; /* current error handling function (stack index) */
10920 +#define G(L) (L->l_G)
10924 +** Union of all collectable objects
10928 + union TString ts;
10930 + union Closure cl;
10934 + struct lua_State th; /* thread */
10938 +/* macros to convert a GCObject into a specific value */
10939 +#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
10940 +#define gco2ts(o) (&rawgco2ts(o)->tsv)
10941 +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
10942 +#define gco2u(o) (&rawgco2u(o)->uv)
10943 +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
10944 +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
10945 +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
10946 +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
10947 +#define ngcotouv(o) \
10948 + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
10949 +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
10951 +/* macro to convert any Lua object into a GCObject */
10952 +#define obj2gco(v) (cast(GCObject *, (v)))
10955 +LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
10956 +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
10961 +++ b/extensions/LUA/lua/lstring.c
10964 +** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
10965 +** String table (keeps all strings handled by Lua)
10966 +** See Copyright Notice in lua.h
10969 +#include <string.h>
10977 +#include "lobject.h"
10978 +#include "lstate.h"
10979 +#include "lstring.h"
10983 +void luaS_resize (lua_State *L, int newsize) {
10984 + GCObject **newhash;
10987 + if (G(L)->gcstate == GCSsweepstring)
10988 + return; /* cannot resize during GC traverse */
10989 + newhash = luaM_newvector(L, newsize, GCObject *);
10990 + tb = &G(L)->strt;
10991 + for (i=0; i<newsize; i++) newhash[i] = NULL;
10993 + for (i=0; i<tb->size; i++) {
10994 + GCObject *p = tb->hash[i];
10995 + while (p) { /* for each node in the list */
10996 + GCObject *next = p->gch.next; /* save next */
10997 + unsigned int h = gco2ts(p)->hash;
10998 + int h1 = lmod(h, newsize); /* new position */
10999 + lua_assert(cast_int(h%newsize) == lmod(h, newsize));
11000 + p->gch.next = newhash[h1]; /* chain it */
11005 + luaM_freearray(L, tb->hash, tb->size, TString *);
11006 + tb->size = newsize;
11007 + tb->hash = newhash;
11011 +static TString *newlstr (lua_State *L, const char *str, size_t l,
11012 + unsigned int h) {
11015 + if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
11017 + ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
11019 + ts->tsv.hash = h;
11020 + ts->tsv.marked = luaC_white(G(L));
11021 + ts->tsv.tt = LUA_TSTRING;
11022 + ts->tsv.reserved = 0;
11023 + memcpy(ts+1, str, l*sizeof(char));
11024 + ((char *)(ts+1))[l] = '\0'; /* ending 0 */
11025 + tb = &G(L)->strt;
11026 + h = lmod(h, tb->size);
11027 + ts->tsv.next = tb->hash[h]; /* chain new entry */
11028 + tb->hash[h] = obj2gco(ts);
11030 + if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
11031 + luaS_resize(L, tb->size*2); /* too crowded */
11036 +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
11038 + unsigned int h = cast(unsigned int, l); /* seed */
11039 + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
11041 + for (l1=l; l1>=step; l1-=step) /* compute hash */
11042 + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
11043 + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
11045 + o = o->gch.next) {
11046 + TString *ts = rawgco2ts(o);
11047 + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
11048 + /* string may be dead */
11049 + if (isdead(G(L), o)) changewhite(o);
11053 + return newlstr(L, str, l, h); /* not found */
11057 +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
11059 + if (s > MAX_SIZET - sizeof(Udata))
11061 + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
11062 + u->uv.marked = luaC_white(G(L)); /* is not finalized */
11063 + u->uv.tt = LUA_TUSERDATA;
11065 + u->uv.metatable = NULL;
11067 + /* chain it on udata list (after main thread) */
11068 + u->uv.next = G(L)->mainthread->next;
11069 + G(L)->mainthread->next = obj2gco(u);
11074 +++ b/extensions/LUA/lua/lstring.h
11077 +** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
11078 +** String table (keep all strings handled by Lua)
11079 +** See Copyright Notice in lua.h
11087 +#include "lobject.h"
11088 +#include "lstate.h"
11091 +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
11093 +#define sizeudata(u) (sizeof(union Udata)+(u)->len)
11095 +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
11096 +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
11097 + (sizeof(s)/sizeof(char))-1))
11099 +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
11101 +LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
11102 +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
11103 +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
11108 +++ b/extensions/LUA/lua/lstrlib.c
11111 +** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
11112 +** Standard library for string operations and pattern-matching
11113 +** See Copyright Notice in lua.h
11117 +#include <ctype.h>
11118 +#include <stddef.h>
11119 +#include <stdio.h>
11120 +#include <stdlib.h>
11121 +#include <string.h>
11128 +#include "lauxlib.h"
11129 +#include "lualib.h"
11132 +/* macro to `unsign' a character */
11133 +#define uchar(c) ((unsigned char)(c))
11137 +static int str_len (lua_State *L) {
11139 + luaL_checklstring(L, 1, &l);
11140 + lua_pushinteger(L, l);
11145 +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
11146 + /* relative string position: negative means back from end */
11147 + if (pos < 0) pos += (ptrdiff_t)len + 1;
11148 + return (pos >= 0) ? pos : 0;
11152 +static int str_sub (lua_State *L) {
11154 + const char *s = luaL_checklstring(L, 1, &l);
11155 + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
11156 + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
11157 + if (start < 1) start = 1;
11158 + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
11159 + if (start <= end)
11160 + lua_pushlstring(L, s+start-1, end-start+1);
11161 + else lua_pushliteral(L, "");
11166 +static int str_reverse (lua_State *L) {
11168 + const char *s = luaL_checklstring(L, 1, &l);
11169 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11170 + if(!b) luaL_error(L, "str_reverse: cannot allocate memory");
11171 + luaL_buffinit(L, b);
11172 + while (l--) luaL_addchar(b, s[l]);
11173 + luaL_pushresult(b);
11179 +static int str_lower (lua_State *L) {
11182 + const char *s = luaL_checklstring(L, 1, &l);
11183 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11184 + if(!b) luaL_error(L, "str_lower: cannot allocate memory");
11185 + luaL_buffinit(L, b);
11186 + for (i=0; i<l; i++)
11187 + luaL_addchar(b, tolower(uchar(s[i])));
11188 + luaL_pushresult(b);
11194 +static int str_upper (lua_State *L) {
11197 + const char *s = luaL_checklstring(L, 1, &l);
11198 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11199 + if(!b) luaL_error(L, "str_upper: cannot allocate memory");
11200 + luaL_buffinit(L, b);
11201 + for (i=0; i<l; i++)
11202 + luaL_addchar(b, toupper(uchar(s[i])));
11203 + luaL_pushresult(b);
11208 +static int str_rep (lua_State *L) {
11210 + const char *s = luaL_checklstring(L, 1, &l);
11211 + int n = luaL_checkint(L, 2);
11212 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11213 + if(!b) luaL_error(L, "str_rep: cannot allocate memory");
11214 + luaL_buffinit(L, b);
11216 + luaL_addlstring(b, s, l);
11217 + luaL_pushresult(b);
11223 +static int str_byte (lua_State *L) {
11225 + const char *s = luaL_checklstring(L, 1, &l);
11226 + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
11227 + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
11229 + if (posi <= 0) posi = 1;
11230 + if ((size_t)pose > l) pose = l;
11231 + if (posi > pose) return 0; /* empty interval; return no values */
11232 + n = (int)(pose - posi + 1);
11233 + if (posi + n <= pose) /* overflow? */
11234 + luaL_error(L, "string slice too long");
11235 + luaL_checkstack(L, n, "string slice too long");
11236 + for (i=0; i<n; i++)
11237 + lua_pushinteger(L, uchar(s[posi+i-1]));
11242 +static int str_char (lua_State *L) {
11243 + int n = lua_gettop(L); /* number of arguments */
11245 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11246 + if(!b) luaL_error(L, "str_char: cannot allocate memory");
11247 + luaL_buffinit(L, b);
11248 + for (i=1; i<=n; i++) {
11249 + int c = luaL_checkint(L, i);
11250 + luaL_argcheck(L, uchar(c) == c, i, "invalid value");
11251 + luaL_addchar(b, uchar(c));
11253 + luaL_pushresult(b);
11259 +static int writer (lua_State *L, const void* b, size_t size, void* B) {
11261 + luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
11266 +static int str_dump (lua_State *L) {
11267 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11268 + if(!b) luaL_error(L, "str_dump: cannot allocate memory");
11269 + luaL_checktype(L, 1, LUA_TFUNCTION);
11270 + lua_settop(L, 1);
11271 + luaL_buffinit(L,b);
11272 + if (lua_dump(L, writer, b) != 0){
11274 + luaL_error(L, "unable to dump given function");
11277 + luaL_pushresult(b);
11285 +** {======================================================
11286 +** PATTERN MATCHING
11287 +** =======================================================
11291 +#define CAP_UNFINISHED (-1)
11292 +#define CAP_POSITION (-2)
11294 +typedef struct MatchState {
11295 + const char *src_init; /* init of source string */
11296 + const char *src_end; /* end (`\0') of source string */
11298 + int level; /* total number of captures (finished or unfinished) */
11300 + const char *init;
11302 + } capture[LUA_MAXCAPTURES];
11307 +#define SPECIALS "^$*+?.([%-"
11310 +static int check_capture (MatchState *ms, int l) {
11312 + if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
11313 + return luaL_error(ms->L, "invalid capture index");
11318 +static int capture_to_close (MatchState *ms) {
11319 + int level = ms->level;
11320 + for (level--; level>=0; level--)
11321 + if (ms->capture[level].len == CAP_UNFINISHED) return level;
11322 + return luaL_error(ms->L, "invalid pattern capture");
11326 +static const char *classend (MatchState *ms, const char *p) {
11330 + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
11334 + if (*p == '^') p++;
11335 + do { /* look for a `]' */
11337 + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
11338 + if (*(p++) == L_ESC && *p != '\0')
11339 + p++; /* skip escapes (e.g. `%]') */
11340 + } while (*p != ']');
11350 +static int match_class (int c, int cl) {
11352 + switch (tolower(cl)) {
11353 + case 'a' : res = isalpha(c); break;
11354 + case 'c' : res = iscntrl(c); break;
11355 + case 'd' : res = isdigit(c); break;
11356 + case 'l' : res = islower(c); break;
11357 + case 'p' : res = ispunct(c); break;
11358 + case 's' : res = isspace(c); break;
11359 + case 'u' : res = isupper(c); break;
11360 + case 'w' : res = isalnum(c); break;
11361 + case 'x' : res = isxdigit(c); break;
11362 + case 'z' : res = (c == 0); break;
11363 + default: return (cl == c);
11365 + return (islower(cl) ? res : !res);
11369 +static int matchbracketclass (int c, const char *p, const char *ec) {
11371 + if (*(p+1) == '^') {
11373 + p++; /* skip the `^' */
11375 + while (++p < ec) {
11376 + if (*p == L_ESC) {
11378 + if (match_class(c, uchar(*p)))
11381 + else if ((*(p+1) == '-') && (p+2 < ec)) {
11383 + if (uchar(*(p-2)) <= c && c <= uchar(*p))
11386 + else if (uchar(*p) == c) return sig;
11392 +static int singlematch (int c, const char *p, const char *ep) {
11394 + case '.': return 1; /* matches any char */
11395 + case L_ESC: return match_class(c, uchar(*(p+1)));
11396 + case '[': return matchbracketclass(c, p, ep-1);
11397 + default: return (uchar(*p) == c);
11402 +static const char *match (MatchState *ms, const char *s, const char *p);
11405 +static const char *matchbalance (MatchState *ms, const char *s,
11407 + if (*p == 0 || *(p+1) == 0)
11408 + luaL_error(ms->L, "unbalanced pattern");
11409 + if (*s != *p) return NULL;
11414 + while (++s < ms->src_end) {
11416 + if (--cont == 0) return s+1;
11418 + else if (*s == b) cont++;
11421 + return NULL; /* string ends out of balance */
11425 +static const char *max_expand (MatchState *ms, const char *s,
11426 + const char *p, const char *ep) {
11427 + ptrdiff_t i = 0; /* counts maximum expand for item */
11428 + while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
11430 + /* keeps trying to match with the maximum repetitions */
11432 + const char *res = match(ms, (s+i), ep+1);
11433 + if (res) return res;
11434 + i--; /* else didn't match; reduce 1 repetition to try again */
11440 +static const char *min_expand (MatchState *ms, const char *s,
11441 + const char *p, const char *ep) {
11443 + const char *res = match(ms, s, ep+1);
11446 + else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
11447 + s++; /* try with one more repetition */
11448 + else return NULL;
11453 +static const char *start_capture (MatchState *ms, const char *s,
11454 + const char *p, int what) {
11456 + int level = ms->level;
11457 + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
11458 + ms->capture[level].init = s;
11459 + ms->capture[level].len = what;
11460 + ms->level = level+1;
11461 + if ((res=match(ms, s, p)) == NULL) /* match failed? */
11462 + ms->level--; /* undo capture */
11467 +static const char *end_capture (MatchState *ms, const char *s,
11469 + int l = capture_to_close(ms);
11471 + ms->capture[l].len = s - ms->capture[l].init; /* close capture */
11472 + if ((res = match(ms, s, p)) == NULL) /* match failed? */
11473 + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
11478 +static const char *match_capture (MatchState *ms, const char *s, int l) {
11480 + l = check_capture(ms, l);
11481 + len = ms->capture[l].len;
11482 + if ((size_t)(ms->src_end-s) >= len &&
11483 + memcmp(ms->capture[l].init, s, len) == 0)
11485 + else return NULL;
11489 +static const char *match (MatchState *ms, const char *s, const char *p) {
11490 + init: /* using goto's to optimize tail recursion */
11492 + case '(': { /* start capture */
11493 + if (*(p+1) == ')') /* position capture? */
11494 + return start_capture(ms, s, p+2, CAP_POSITION);
11496 + return start_capture(ms, s, p+1, CAP_UNFINISHED);
11498 + case ')': { /* end capture */
11499 + return end_capture(ms, s, p+1);
11502 + switch (*(p+1)) {
11503 + case 'b': { /* balanced string? */
11504 + s = matchbalance(ms, s, p+2);
11505 + if (s == NULL) return NULL;
11506 + p+=4; goto init; /* else return match(ms, s, p+4); */
11508 + case 'f': { /* frontier? */
11509 + const char *ep; char previous;
11512 + luaL_error(ms->L, "missing " LUA_QL("[") " after "
11513 + LUA_QL("%%f") " in pattern");
11514 + ep = classend(ms, p); /* points to what is next */
11515 + previous = (s == ms->src_init) ? '\0' : *(s-1);
11516 + if (matchbracketclass(uchar(previous), p, ep-1) ||
11517 + !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
11518 + p=ep; goto init; /* else return match(ms, s, ep); */
11521 + if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
11522 + s = match_capture(ms, s, uchar(*(p+1)));
11523 + if (s == NULL) return NULL;
11524 + p+=2; goto init; /* else return match(ms, s, p+2) */
11526 + goto dflt; /* case default */
11530 + case '\0': { /* end of pattern */
11531 + return s; /* match succeeded */
11534 + if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
11535 + return (s == ms->src_end) ? s : NULL; /* check end of string */
11538 + default: dflt: { /* it is a pattern item */
11539 + const char *ep = classend(ms, p); /* points to what is next */
11540 + int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
11542 + case '?': { /* optional */
11544 + if (m && ((res=match(ms, s+1, ep+1)) != NULL))
11546 + p=ep+1; goto init; /* else return match(ms, s, ep+1); */
11548 + case '*': { /* 0 or more repetitions */
11549 + return max_expand(ms, s, p, ep);
11551 + case '+': { /* 1 or more repetitions */
11552 + return (m ? max_expand(ms, s+1, p, ep) : NULL);
11554 + case '-': { /* 0 or more repetitions (minimum) */
11555 + return min_expand(ms, s, p, ep);
11558 + if (!m) return NULL;
11559 + s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
11568 +static const char *lmemfind (const char *s1, size_t l1,
11569 + const char *s2, size_t l2) {
11570 + if (l2 == 0) return s1; /* empty strings are everywhere */
11571 + else if (l2 > l1) return NULL; /* avoids a negative `l1' */
11573 + const char *init; /* to search for a `*s2' inside `s1' */
11574 + l2--; /* 1st char will be checked by `memchr' */
11575 + l1 = l1-l2; /* `s2' cannot be found after that */
11576 + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
11577 + init++; /* 1st char is already checked */
11578 + if (memcmp(init, s2+1, l2) == 0)
11580 + else { /* correct `l1' and `s1' to try again */
11585 + return NULL; /* not found */
11590 +static void push_onecapture (MatchState *ms, int i, const char *s,
11592 + if (i >= ms->level) {
11593 + if (i == 0) /* ms->level == 0, too */
11594 + lua_pushlstring(ms->L, s, e - s); /* add whole match */
11596 + luaL_error(ms->L, "invalid capture index");
11599 + ptrdiff_t l = ms->capture[i].len;
11600 + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
11601 + if (l == CAP_POSITION)
11602 + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
11604 + lua_pushlstring(ms->L, ms->capture[i].init, l);
11609 +static int push_captures (MatchState *ms, const char *s, const char *e) {
11611 + int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
11612 + luaL_checkstack(ms->L, nlevels, "too many captures");
11613 + for (i = 0; i < nlevels; i++)
11614 + push_onecapture(ms, i, s, e);
11615 + return nlevels; /* number of strings pushed */
11619 +static int str_find_aux (lua_State *L, int find) {
11621 + const char *s = luaL_checklstring(L, 1, &l1);
11622 + const char *p = luaL_checklstring(L, 2, &l2);
11623 + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
11624 + if (init < 0) init = 0;
11625 + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
11626 + if (find && (lua_toboolean(L, 4) || /* explicit request? */
11627 + strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
11628 + /* do a plain search */
11629 + const char *s2 = lmemfind(s+init, l1-init, p, l2);
11631 + lua_pushinteger(L, s2-s+1);
11632 + lua_pushinteger(L, s2-s+l2);
11638 + int anchor = (*p == '^') ? (p++, 1) : 0;
11639 + const char *s1=s+init;
11642 + ms.src_end = s+l1;
11646 + if ((res=match(&ms, s1, p)) != NULL) {
11648 + lua_pushinteger(L, s1-s+1); /* start */
11649 + lua_pushinteger(L, res-s); /* end */
11650 + return push_captures(&ms, NULL, 0) + 2;
11653 + return push_captures(&ms, s1, res);
11655 + } while (s1++ < ms.src_end && !anchor);
11657 + lua_pushnil(L); /* not found */
11662 +static int str_find (lua_State *L) {
11663 + return str_find_aux(L, 1);
11667 +static int str_match (lua_State *L) {
11668 + return str_find_aux(L, 0);
11672 +static int gmatch_aux (lua_State *L) {
11675 + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
11676 + const char *p = lua_tostring(L, lua_upvalueindex(2));
11680 + ms.src_end = s+ls;
11681 + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
11682 + src <= ms.src_end;
11686 + if ((e = match(&ms, src, p)) != NULL) {
11687 + lua_Integer newstart = e-s;
11688 + if (e == src) newstart++; /* empty match? go at least one position */
11689 + lua_pushinteger(L, newstart);
11690 + lua_replace(L, lua_upvalueindex(3));
11691 + return push_captures(&ms, src, e);
11694 + return 0; /* not found */
11698 +static int gmatch (lua_State *L) {
11699 + luaL_checkstring(L, 1);
11700 + luaL_checkstring(L, 2);
11701 + lua_settop(L, 2);
11702 + lua_pushinteger(L, 0);
11703 + lua_pushcclosure(L, gmatch_aux, 3);
11708 +static int gfind_nodef (lua_State *L) {
11709 + return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
11710 + LUA_QL("string.gmatch"));
11714 +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
11717 + const char *news = lua_tolstring(ms->L, 3, &l);
11718 + for (i = 0; i < l; i++) {
11719 + if (news[i] != L_ESC)
11720 + luaL_addchar(b, news[i]);
11722 + i++; /* skip ESC */
11723 + if (!isdigit(uchar(news[i])))
11724 + luaL_addchar(b, news[i]);
11725 + else if (news[i] == '0')
11726 + luaL_addlstring(b, s, e - s);
11728 + push_onecapture(ms, news[i] - '1', s, e);
11729 + luaL_addvalue(b); /* add capture to accumulated result */
11736 +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
11738 + lua_State *L = ms->L;
11739 + switch (lua_type(L, 3)) {
11740 + case LUA_TNUMBER:
11741 + case LUA_TSTRING: {
11742 + add_s(ms, b, s, e);
11745 + case LUA_TFUNCTION: {
11747 + lua_pushvalue(L, 3);
11748 + n = push_captures(ms, s, e);
11749 + lua_call(L, n, 1);
11752 + case LUA_TTABLE: {
11753 + push_onecapture(ms, 0, s, e);
11754 + lua_gettable(L, 3);
11758 + if (!lua_toboolean(L, -1)) { /* nil or false? */
11760 + lua_pushlstring(L, s, e - s); /* keep original text */
11762 + else if (!lua_isstring(L, -1))
11763 + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
11764 + luaL_addvalue(b); /* add result to accumulator */
11768 +static int str_gsub (lua_State *L) {
11770 + const char *src = luaL_checklstring(L, 1, &srcl);
11771 + const char *p = luaL_checkstring(L, 2);
11772 + int tr = lua_type(L, 3);
11773 + int max_s = luaL_optint(L, 4, srcl+1);
11774 + int anchor = (*p == '^') ? (p++, 1) : 0;
11777 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11778 + if(!b) luaL_error(L, "str_gsub: cannot allocate memory");
11779 + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
11780 + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
11781 + "string/function/table expected");
11782 + luaL_buffinit(L, b);
11784 + ms.src_init = src;
11785 + ms.src_end = src+srcl;
11786 + while (n < max_s) {
11789 + e = match(&ms, src, p);
11792 + add_value(&ms, b, src, e);
11794 + if (e && e>src) /* non empty match? */
11795 + src = e; /* skip it */
11796 + else if (src < ms.src_end)
11797 + luaL_addchar(b, *src++);
11799 + if (anchor) break;
11801 + luaL_addlstring(b, src, ms.src_end-src);
11802 + luaL_pushresult(b);
11803 + lua_pushinteger(L, n); /* number of substitutions */
11808 +/* }====================================================== */
11811 +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
11812 +#define MAX_ITEM 512
11813 +/* valid flags in a format specification */
11814 +#define FLAGS "-+ #0"
11816 +** maximum size of each format specification (such as '%-099.99d')
11817 +** (+10 accounts for %99.99x plus margin of error)
11819 +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
11822 +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
11824 + const char *s = luaL_checklstring(L, arg, &l);
11825 + luaL_addchar(b, '"');
11828 + case '"': case '\\': case '\n': {
11829 + luaL_addchar(b, '\\');
11830 + luaL_addchar(b, *s);
11834 + luaL_addlstring(b, "\\r", 2);
11838 + luaL_addlstring(b, "\\000", 4);
11842 + luaL_addchar(b, *s);
11848 + luaL_addchar(b, '"');
11851 +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
11852 + const char *p = strfrmt;
11853 + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
11854 + if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
11855 + luaL_error(L, "invalid format (repeated flags)");
11856 + if (isdigit(uchar(*p))) p++; /* skip width */
11857 + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
11860 + if (isdigit(uchar(*p))) p++; /* skip precision */
11861 + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
11863 + if (isdigit(uchar(*p)))
11864 + luaL_error(L, "invalid format (width or precision too long)");
11866 + strncpy(form, strfrmt, p - strfrmt + 1);
11867 + form += p - strfrmt + 1;
11873 +static void addintlen (char *form) {
11874 + size_t l = strlen(form);
11875 + char spec = form[l - 1];
11876 + strcpy(form + l - 1, LUA_INTFRMLEN);
11877 + form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
11878 + form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
11882 +static int str_format (lua_State *L) {
11885 + const char *strfrmt = luaL_checklstring(L, arg, &sfl);
11886 + const char *strfrmt_end = strfrmt+sfl;
11887 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
11888 + if(!b) luaL_error(L, "str_format: cannot allocate memory");
11889 + luaL_buffinit(L, b);
11890 + while (strfrmt < strfrmt_end) {
11891 + if (*strfrmt != L_ESC)
11892 + luaL_addchar(b, *strfrmt++);
11893 + else if (*++strfrmt == L_ESC)
11894 + luaL_addchar(b, *strfrmt++); /* %% */
11895 + else { /* format item */
11896 + char form[MAX_FORMAT]; /* to store the format (`%...') */
11897 + char buff[MAX_ITEM]; /* to store the formatted item */
11899 + strfrmt = scanformat(L, strfrmt, form);
11900 + switch (*strfrmt++) {
11902 + sprintf(buff, form, (int)luaL_checknumber(L, arg));
11905 + case 'd': case 'i': {
11907 + sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
11910 + case 'o': case 'u': case 'x': case 'X': {
11912 + sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
11916 + addquoted(L, b, arg);
11917 + continue; /* skip the 'addsize' at the end */
11921 + const char *s = luaL_checklstring(L, arg, &l);
11922 + if (!strchr(form, '.') && l >= 100) {
11923 + /* no precision and string is too long to be formatted;
11924 + keep original string */
11925 + lua_pushvalue(L, arg);
11926 + luaL_addvalue(b);
11927 + continue; /* skip the `addsize' at the end */
11930 + sprintf(buff, form, s);
11934 + default: { /* also treat cases `pnLlh' */
11936 + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
11937 + LUA_QL("format"), *(strfrmt - 1));
11940 + luaL_addlstring(b, buff, strlen(buff));
11943 + luaL_pushresult(b);
11949 +static const luaL_Reg strlib[] = {
11950 + {"byte", str_byte},
11951 + {"char", str_char},
11952 + {"dump", str_dump},
11953 + {"find", str_find},
11954 + {"format", str_format},
11955 + {"gfind", gfind_nodef},
11956 + {"gmatch", gmatch},
11957 + {"gsub", str_gsub},
11958 + {"len", str_len},
11959 + {"lower", str_lower},
11960 + {"match", str_match},
11961 + {"rep", str_rep},
11962 + {"reverse", str_reverse},
11963 + {"sub", str_sub},
11964 + {"upper", str_upper},
11969 +static void createmetatable (lua_State *L) {
11970 + lua_createtable(L, 0, 1); /* create metatable for strings */
11971 + lua_pushliteral(L, ""); /* dummy string */
11972 + lua_pushvalue(L, -2);
11973 + lua_setmetatable(L, -2); /* set string metatable */
11974 + lua_pop(L, 1); /* pop dummy string */
11975 + lua_pushvalue(L, -2); /* string library... */
11976 + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
11977 + lua_pop(L, 1); /* pop metatable */
11982 +** Open string library
11984 +LUALIB_API int luaopen_string (lua_State *L) {
11985 + luaL_register(L, LUA_STRLIBNAME, strlib);
11986 +#if defined(LUA_COMPAT_GFIND)
11987 + lua_getfield(L, -1, "gmatch");
11988 + lua_setfield(L, -2, "gfind");
11990 + createmetatable(L);
11994 +++ b/extensions/LUA/lua/ltable.c
11997 +** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $
11998 +** Lua tables (hash)
11999 +** See Copyright Notice in lua.h
12004 +** Implementation of tables (aka arrays, objects, or hash tables).
12005 +** Tables keep its elements in two parts: an array part and a hash part.
12006 +** Non-negative integer keys are all candidates to be kept in the array
12007 +** part. The actual size of the array is the largest `n' such that at
12008 +** least half the slots between 0 and n are in use.
12009 +** Hash uses a mix of chained scatter table with Brent's variation.
12010 +** A main invariant of these tables is that, if an element is not
12011 +** in its main position (i.e. the `original' position that its hash gives
12012 +** to it), then the colliding element is in its own main position.
12013 +** Hence even when the load factor reaches 100%, performance remains good.
12017 +#include <string.h>
12024 +#include "ldebug.h"
12028 +#include "lobject.h"
12029 +#include "lstate.h"
12030 +#include "ltable.h"
12034 +** max size of array part is 2^MAXBITS
12036 +#if LUAI_BITSINT > 26
12037 +#define MAXBITS 26
12039 +#define MAXBITS (LUAI_BITSINT-2)
12042 +#define MAXASIZE (1 << MAXBITS)
12045 +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
12047 +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
12048 +#define hashboolean(t,p) hashpow2(t, p)
12052 +** for some types, it is better to avoid modulus by power of 2, as
12053 +** they tend to have many 2 factors.
12055 +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
12058 +#define hashpointer(t,p) hashmod(t, IntPoint(p))
12062 +** number of ints inside a lua_Number
12064 +#define numints cast_int(sizeof(lua_Number)/sizeof(int))
12068 +#define dummynode (&dummynode_)
12070 +static const Node dummynode_ = {
12071 + {{NULL}, LUA_TNIL}, /* value */
12072 + {{{NULL}, LUA_TNIL, NULL}} /* key */
12077 +** hash for lua_Numbers
12079 +static Node *hashnum (const Table *t, lua_Number n) {
12080 + unsigned int a[numints];
12082 + if (luai_numeq(n, 0)) /* avoid problems with -0 */
12083 + return gnode(t, 0);
12084 + memcpy(a, &n, sizeof(a));
12085 + for (i = 1; i < numints; i++) a[0] += a[i];
12086 + return hashmod(t, a[0]);
12092 +** returns the `main' position of an element in a table (that is, the index
12093 +** of its hash value)
12095 +static Node *mainposition (const Table *t, const TValue *key) {
12096 + switch (ttype(key)) {
12097 + case LUA_TNUMBER:
12098 + return hashnum(t, nvalue(key));
12099 + case LUA_TSTRING:
12100 + return hashstr(t, rawtsvalue(key));
12101 + case LUA_TBOOLEAN:
12102 + return hashboolean(t, bvalue(key));
12103 + case LUA_TLIGHTUSERDATA:
12104 + return hashpointer(t, pvalue(key));
12106 + return hashpointer(t, gcvalue(key));
12112 +** returns the index for `key' if `key' is an appropriate key to live in
12113 +** the array part of the table, -1 otherwise.
12115 +static int arrayindex (const TValue *key) {
12116 + if (ttisnumber(key)) {
12117 + lua_Number n = nvalue(key);
12119 + lua_number2int(k, n);
12120 + if (luai_numeq(cast_num(k), n))
12123 + return -1; /* `key' did not match some condition */
12128 +** returns the index of a `key' for table traversals. First goes all
12129 +** elements in the array part, then elements in the hash part. The
12130 +** beginning of a traversal is signalled by -1.
12132 +static int findindex (lua_State *L, Table *t, StkId key) {
12134 + if (ttisnil(key)) return -1; /* first iteration */
12135 + i = arrayindex(key);
12136 + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
12137 + return i-1; /* yes; that's the index (corrected to C) */
12139 + Node *n = mainposition(t, key);
12140 + do { /* check whether `key' is somewhere in the chain */
12141 + /* key may be dead already, but it is ok to use it in `next' */
12142 + if (luaO_rawequalObj(key2tval(n), key) ||
12143 + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
12144 + gcvalue(gkey(n)) == gcvalue(key))) {
12145 + i = cast_int(n - gnode(t, 0)); /* key index in hash table */
12146 + /* hash elements are numbered after array ones */
12147 + return i + t->sizearray;
12149 + else n = gnext(n);
12151 + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
12152 + return 0; /* to avoid warnings */
12157 +int luaH_next (lua_State *L, Table *t, StkId key) {
12158 + int i = findindex(L, t, key); /* find original element */
12159 + for (i++; i < t->sizearray; i++) { /* try first array part */
12160 + if (!ttisnil(&t->array[i])) { /* a non-nil value? */
12161 + setnvalue(key, cast_num(i+1));
12162 + setobj2s(L, key+1, &t->array[i]);
12166 + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
12167 + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
12168 + setobj2s(L, key, key2tval(gnode(t, i)));
12169 + setobj2s(L, key+1, gval(gnode(t, i)));
12173 + return 0; /* no more elements */
12178 +** {=============================================================
12180 +** ==============================================================
12184 +static int computesizes (int nums[], int *narray) {
12186 + int twotoi; /* 2^i */
12187 + int a = 0; /* number of elements smaller than 2^i */
12188 + int na = 0; /* number of elements to go to array part */
12189 + int n = 0; /* optimal size for array part */
12190 + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
12191 + if (nums[i] > 0) {
12193 + if (a > twotoi/2) { /* more than half elements present? */
12194 + n = twotoi; /* optimal size (till now) */
12195 + na = a; /* all elements smaller than n will go to array part */
12198 + if (a == *narray) break; /* all elements already counted */
12201 + lua_assert(*narray/2 <= na && na <= *narray);
12206 +static int countint (const TValue *key, int *nums) {
12207 + int k = arrayindex(key);
12208 + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
12209 + nums[ceillog2(k)]++; /* count as such */
12217 +static int numusearray (const Table *t, int *nums) {
12219 + int ttlg; /* 2^lg */
12220 + int ause = 0; /* summation of `nums' */
12221 + int i = 1; /* count to traverse all array keys */
12222 + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
12223 + int lc = 0; /* counter */
12225 + if (lim > t->sizearray) {
12226 + lim = t->sizearray; /* adjust upper limit */
12228 + break; /* no more elements to count */
12230 + /* count elements in range (2^(lg-1), 2^lg] */
12231 + for (; i <= lim; i++) {
12232 + if (!ttisnil(&t->array[i-1]))
12242 +static int numusehash (const Table *t, int *nums, int *pnasize) {
12243 + int totaluse = 0; /* total number of elements */
12244 + int ause = 0; /* summation of `nums' */
12245 + int i = sizenode(t);
12247 + Node *n = &t->node[i];
12248 + if (!ttisnil(gval(n))) {
12249 + ause += countint(key2tval(n), nums);
12253 + *pnasize += ause;
12258 +static void setarrayvector (lua_State *L, Table *t, int size) {
12260 + luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
12261 + for (i=t->sizearray; i<size; i++)
12262 + setnilvalue(&t->array[i]);
12263 + t->sizearray = size;
12267 +static void setnodevector (lua_State *L, Table *t, int size) {
12269 + if (size == 0) { /* no elements to hash part? */
12270 + t->node = cast(Node *, dummynode); /* use common `dummynode' */
12275 + lsize = ceillog2(size);
12276 + if (lsize > MAXBITS)
12277 + luaG_runerror(L, "table overflow");
12278 + size = twoto(lsize);
12279 + t->node = luaM_newvector(L, size, Node);
12280 + for (i=0; i<size; i++) {
12281 + Node *n = gnode(t, i);
12283 + setnilvalue(gkey(n));
12284 + setnilvalue(gval(n));
12287 + t->lsizenode = cast_byte(lsize);
12288 + t->lastfree = gnode(t, size); /* all positions are free */
12292 +static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
12294 + int oldasize = t->sizearray;
12295 + int oldhsize = t->lsizenode;
12296 + Node *nold = t->node; /* save old hash ... */
12297 + if (nasize > oldasize) /* array part must grow? */
12298 + setarrayvector(L, t, nasize);
12299 + /* create new hash part with appropriate size */
12300 + setnodevector(L, t, nhsize);
12301 + if (nasize < oldasize) { /* array part must shrink? */
12302 + t->sizearray = nasize;
12303 + /* re-insert elements from vanishing slice */
12304 + for (i=nasize; i<oldasize; i++) {
12305 + if (!ttisnil(&t->array[i]))
12306 + setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
12308 + /* shrink array */
12309 + luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
12311 + /* re-insert elements from hash part */
12312 + for (i = twoto(oldhsize) - 1; i >= 0; i--) {
12313 + Node *old = nold+i;
12314 + if (!ttisnil(gval(old)))
12315 + setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
12317 + if (nold != dummynode)
12318 + luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
12322 +void luaH_resizearray (lua_State *L, Table *t, int nasize) {
12323 + int nsize = (t->node == dummynode) ? 0 : sizenode(t);
12324 + resize(L, t, nasize, nsize);
12328 +static void rehash (lua_State *L, Table *t, const TValue *ek) {
12330 + int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
12333 + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
12334 + nasize = numusearray(t, nums); /* count keys in array part */
12335 + totaluse = nasize; /* all those keys are integer keys */
12336 + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
12337 + /* count extra key */
12338 + nasize += countint(ek, nums);
12340 + /* compute new size for array part */
12341 + na = computesizes(nums, &nasize);
12342 + /* resize the table to new computed sizes */
12343 + resize(L, t, nasize, totaluse - na);
12349 +** }=============================================================
12353 +Table *luaH_new (lua_State *L, int narray, int nhash) {
12354 + Table *t = luaM_new(L, Table);
12355 + luaC_link(L, obj2gco(t), LUA_TTABLE);
12356 + t->metatable = NULL;
12357 + t->flags = cast_byte(~0);
12358 + /* temporary values (kept only if some malloc fails) */
12360 + t->sizearray = 0;
12361 + t->lsizenode = 0;
12362 + t->node = cast(Node *, dummynode);
12363 + setarrayvector(L, t, narray);
12364 + setnodevector(L, t, nhash);
12369 +void luaH_free (lua_State *L, Table *t) {
12370 + if (t->node != dummynode)
12371 + luaM_freearray(L, t->node, sizenode(t), Node);
12372 + luaM_freearray(L, t->array, t->sizearray, TValue);
12377 +static Node *getfreepos (Table *t) {
12378 + while (t->lastfree-- > t->node) {
12379 + if (ttisnil(gkey(t->lastfree)))
12380 + return t->lastfree;
12382 + return NULL; /* could not find a free place */
12388 +** inserts a new key into a hash table; first, check whether key's main
12389 +** position is free. If not, check whether colliding node is in its main
12390 +** position or not: if it is not, move colliding node to an empty place and
12391 +** put new key in its main position; otherwise (colliding node is in its main
12392 +** position), new key goes to an empty position.
12394 +static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
12395 + Node *mp = mainposition(t, key);
12396 + if (!ttisnil(gval(mp)) || mp == dummynode) {
12398 + Node *n = getfreepos(t); /* get a free place */
12399 + if (n == NULL) { /* cannot find a free place? */
12400 + rehash(L, t, key); /* grow table */
12401 + return luaH_set(L, t, key); /* re-insert key into grown table */
12403 + lua_assert(n != dummynode);
12404 + othern = mainposition(t, key2tval(mp));
12405 + if (othern != mp) { /* is colliding node out of its main position? */
12406 + /* yes; move colliding node into free position */
12407 + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
12408 + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
12409 + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
12410 + gnext(mp) = NULL; /* now `mp' is free */
12411 + setnilvalue(gval(mp));
12413 + else { /* colliding node is in its own main position */
12414 + /* new node will go into free position */
12415 + gnext(n) = gnext(mp); /* chain new position */
12420 + gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
12421 + luaC_barriert(L, t, key);
12422 + lua_assert(ttisnil(gval(mp)));
12428 +** search function for integers
12430 +const TValue *luaH_getnum (Table *t, int key) {
12431 + /* (1 <= key && key <= t->sizearray) */
12432 + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
12433 + return &t->array[key-1];
12435 + lua_Number nk = cast_num(key);
12436 + Node *n = hashnum(t, nk);
12437 + do { /* check whether `key' is somewhere in the chain */
12438 + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
12439 + return gval(n); /* that's it */
12440 + else n = gnext(n);
12442 + return luaO_nilobject;
12448 +** search function for strings
12450 +const TValue *luaH_getstr (Table *t, TString *key) {
12451 + Node *n = hashstr(t, key);
12452 + do { /* check whether `key' is somewhere in the chain */
12453 + if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
12454 + return gval(n); /* that's it */
12455 + else n = gnext(n);
12457 + return luaO_nilobject;
12462 +** main search function
12464 +const TValue *luaH_get (Table *t, const TValue *key) {
12465 + switch (ttype(key)) {
12466 + case LUA_TNIL: return luaO_nilobject;
12467 + case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
12468 + case LUA_TNUMBER: {
12470 + lua_Number n = nvalue(key);
12471 + lua_number2int(k, n);
12472 + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
12473 + return luaH_getnum(t, k); /* use specialized version */
12474 + /* else go through */
12477 + Node *n = mainposition(t, key);
12478 + do { /* check whether `key' is somewhere in the chain */
12479 + if (luaO_rawequalObj(key2tval(n), key))
12480 + return gval(n); /* that's it */
12481 + else n = gnext(n);
12483 + return luaO_nilobject;
12489 +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
12490 + const TValue *p = luaH_get(t, key);
12492 + if (p != luaO_nilobject)
12493 + return cast(TValue *, p);
12495 + if (ttisnil(key)) luaG_runerror(L, "table index is nil");
12496 + else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
12497 + luaG_runerror(L, "table index is NaN");
12498 + return newkey(L, t, key);
12503 +TValue *luaH_setnum (lua_State *L, Table *t, int key) {
12504 + const TValue *p = luaH_getnum(t, key);
12505 + if (p != luaO_nilobject)
12506 + return cast(TValue *, p);
12509 + setnvalue(&k, cast_num(key));
12510 + return newkey(L, t, &k);
12515 +TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
12516 + const TValue *p = luaH_getstr(t, key);
12517 + if (p != luaO_nilobject)
12518 + return cast(TValue *, p);
12521 + setsvalue(L, &k, key);
12522 + return newkey(L, t, &k);
12527 +static int unbound_search (Table *t, unsigned int j) {
12528 + unsigned int i = j; /* i is zero or a present index */
12530 + /* find `i' and `j' such that i is present and j is not */
12531 + while (!ttisnil(luaH_getnum(t, j))) {
12534 + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
12535 + /* table was built with bad purposes: resort to linear search */
12537 + while (!ttisnil(luaH_getnum(t, i))) i++;
12541 + /* now do a binary search between them */
12542 + while (j - i > 1) {
12543 + unsigned int m = (i+j)/2;
12544 + if (ttisnil(luaH_getnum(t, m))) j = m;
12552 +** Try to find a boundary in table `t'. A `boundary' is an integer index
12553 +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
12555 +int luaH_getn (Table *t) {
12556 + unsigned int j = t->sizearray;
12557 + if (j > 0 && ttisnil(&t->array[j - 1])) {
12558 + /* there is a boundary in the array part: (binary) search for it */
12559 + unsigned int i = 0;
12560 + while (j - i > 1) {
12561 + unsigned int m = (i+j)/2;
12562 + if (ttisnil(&t->array[m - 1])) j = m;
12567 + /* else must find a boundary in hash part */
12568 + else if (t->node == dummynode) /* hash part is empty? */
12569 + return j; /* that is easy... */
12570 + else return unbound_search(t, j);
12575 +#if defined(LUA_DEBUG)
12577 +Node *luaH_mainposition (const Table *t, const TValue *key) {
12578 + return mainposition(t, key);
12581 +int luaH_isdummy (Node *n) { return n == dummynode; }
12585 +++ b/extensions/LUA/lua/ltable.h
12588 +** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
12589 +** Lua tables (hash)
12590 +** See Copyright Notice in lua.h
12596 +#include "lobject.h"
12599 +#define gnode(t,i) (&(t)->node[i])
12600 +#define gkey(n) (&(n)->i_key.nk)
12601 +#define gval(n) (&(n)->i_val)
12602 +#define gnext(n) ((n)->i_key.nk.next)
12604 +#define key2tval(n) (&(n)->i_key.tvk)
12607 +LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
12608 +LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
12609 +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
12610 +LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
12611 +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
12612 +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
12613 +LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
12614 +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
12615 +LUAI_FUNC void luaH_free (lua_State *L, Table *t);
12616 +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
12617 +LUAI_FUNC int luaH_getn (Table *t);
12620 +#if defined(LUA_DEBUG)
12621 +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
12622 +LUAI_FUNC int luaH_isdummy (Node *n);
12628 +++ b/extensions/LUA/lua/ltablib.c
12631 +** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
12632 +** Library for Table Manipulation
12633 +** See Copyright Notice in lua.h
12637 +#include <stddef.h>
12644 +#include "lauxlib.h"
12645 +#include "lualib.h"
12648 +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
12651 +static int foreachi (lua_State *L) {
12653 + int n = aux_getn(L, 1);
12654 + luaL_checktype(L, 2, LUA_TFUNCTION);
12655 + for (i=1; i <= n; i++) {
12656 + lua_pushvalue(L, 2); /* function */
12657 + lua_pushinteger(L, i); /* 1st argument */
12658 + lua_rawgeti(L, 1, i); /* 2nd argument */
12659 + lua_call(L, 2, 1);
12660 + if (!lua_isnil(L, -1))
12662 + lua_pop(L, 1); /* remove nil result */
12668 +static int foreach (lua_State *L) {
12669 + luaL_checktype(L, 1, LUA_TTABLE);
12670 + luaL_checktype(L, 2, LUA_TFUNCTION);
12671 + lua_pushnil(L); /* first key */
12672 + while (lua_next(L, 1)) {
12673 + lua_pushvalue(L, 2); /* function */
12674 + lua_pushvalue(L, -3); /* key */
12675 + lua_pushvalue(L, -3); /* value */
12676 + lua_call(L, 2, 1);
12677 + if (!lua_isnil(L, -1))
12679 + lua_pop(L, 2); /* remove value and result */
12685 +static int maxn (lua_State *L) {
12686 + lua_Number max = 0;
12687 + luaL_checktype(L, 1, LUA_TTABLE);
12688 + lua_pushnil(L); /* first key */
12689 + while (lua_next(L, 1)) {
12690 + lua_pop(L, 1); /* remove value */
12691 + if (lua_type(L, -1) == LUA_TNUMBER) {
12692 + lua_Number v = lua_tonumber(L, -1);
12693 + if (v > max) max = v;
12696 + lua_pushnumber(L, max);
12701 +static int getn (lua_State *L) {
12702 + lua_pushinteger(L, aux_getn(L, 1));
12707 +static int setn (lua_State *L) {
12708 + luaL_checktype(L, 1, LUA_TTABLE);
12710 + luaL_setn(L, 1, luaL_checkint(L, 2));
12712 + luaL_error(L, LUA_QL("setn") " is obsolete");
12714 + lua_pushvalue(L, 1);
12719 +static int tinsert (lua_State *L) {
12720 + int e = aux_getn(L, 1) + 1; /* first empty element */
12721 + int pos; /* where to insert new element */
12722 + switch (lua_gettop(L)) {
12723 + case 2: { /* called with only 2 arguments */
12724 + pos = e; /* insert new element at the end */
12729 + pos = luaL_checkint(L, 2); /* 2nd argument is the position */
12730 + if (pos > e) e = pos; /* `grow' array if necessary */
12731 + for (i = e; i > pos; i--) { /* move up elements */
12732 + lua_rawgeti(L, 1, i-1);
12733 + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
12738 + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
12741 + luaL_setn(L, 1, e); /* new size */
12742 + lua_rawseti(L, 1, pos); /* t[pos] = v */
12747 +static int tremove (lua_State *L) {
12748 + int e = aux_getn(L, 1);
12749 + int pos = luaL_optint(L, 2, e);
12750 + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
12751 + return 0; /* nothing to remove */
12752 + luaL_setn(L, 1, e - 1); /* t.n = n-1 */
12753 + lua_rawgeti(L, 1, pos); /* result = t[pos] */
12754 + for ( ;pos<e; pos++) {
12755 + lua_rawgeti(L, 1, pos+1);
12756 + lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
12759 + lua_rawseti(L, 1, e); /* t[e] = nil */
12764 +static void addfield (lua_State *L, luaL_Buffer *b, int i) {
12765 + lua_rawgeti(L, 1, i);
12766 + if (!lua_isstring(L, -1))
12767 + luaL_error(L, "invalid value (%s) at index %d in table for "
12768 + LUA_QL("concat"), luaL_typename(L, -1), i);
12769 + luaL_addvalue(b);
12773 +static int tconcat (lua_State *L) {
12776 + const char *sep = luaL_optlstring(L, 2, "", &lsep);
12777 + luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
12778 + if(!b) luaL_error(L, "tconcat: cannot allocate memory");
12779 + luaL_checktype(L, 1, LUA_TTABLE);
12780 + i = luaL_optint(L, 3, 1);
12781 + last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
12782 + luaL_buffinit(L, b);
12783 + for (; i < last; i++) {
12784 + addfield(L, b, i);
12785 + luaL_addlstring(b, sep, lsep);
12787 + if (i == last) /* add last value (if interval was not empty) */
12788 + addfield(L, b, i);
12789 + luaL_pushresult(b);
12797 +** {======================================================
12799 +** (based on `Algorithms in MODULA-3', Robert Sedgewick;
12800 +** Addison-Wesley, 1993.)
12804 +static void set2 (lua_State *L, int i, int j) {
12805 + lua_rawseti(L, 1, i);
12806 + lua_rawseti(L, 1, j);
12809 +static int sort_comp (lua_State *L, int a, int b) {
12810 + if (!lua_isnil(L, 2)) { /* function? */
12812 + lua_pushvalue(L, 2);
12813 + lua_pushvalue(L, a-1); /* -1 to compensate function */
12814 + lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
12815 + lua_call(L, 2, 1);
12816 + res = lua_toboolean(L, -1);
12820 + else /* a < b? */
12821 + return lua_lessthan(L, a, b);
12824 +static void auxsort (lua_State *L, int l, int u) {
12825 + while (l < u) { /* for tail recursion */
12827 + /* sort elements a[l], a[(l+u)/2] and a[u] */
12828 + lua_rawgeti(L, 1, l);
12829 + lua_rawgeti(L, 1, u);
12830 + if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
12831 + set2(L, l, u); /* swap a[l] - a[u] */
12834 + if (u-l == 1) break; /* only 2 elements */
12836 + lua_rawgeti(L, 1, i);
12837 + lua_rawgeti(L, 1, l);
12838 + if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
12841 + lua_pop(L, 1); /* remove a[l] */
12842 + lua_rawgeti(L, 1, u);
12843 + if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
12848 + if (u-l == 2) break; /* only 3 elements */
12849 + lua_rawgeti(L, 1, i); /* Pivot */
12850 + lua_pushvalue(L, -1);
12851 + lua_rawgeti(L, 1, u-1);
12853 + /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
12855 + for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
12856 + /* repeat ++i until a[i] >= P */
12857 + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
12858 + if (i>u) luaL_error(L, "invalid order function for sorting");
12859 + lua_pop(L, 1); /* remove a[i] */
12861 + /* repeat --j until a[j] <= P */
12862 + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
12863 + if (j<l) luaL_error(L, "invalid order function for sorting");
12864 + lua_pop(L, 1); /* remove a[j] */
12867 + lua_pop(L, 3); /* pop pivot, a[i], a[j] */
12872 + lua_rawgeti(L, 1, u-1);
12873 + lua_rawgeti(L, 1, i);
12874 + set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
12875 + /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
12876 + /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
12878 + j=l; i=i-1; l=i+2;
12881 + j=i+1; i=u; u=j-2;
12883 + auxsort(L, j, i); /* call recursively the smaller one */
12884 + } /* repeat the routine for the larger one */
12887 +static int sort (lua_State *L) {
12888 + int n = aux_getn(L, 1);
12889 + luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
12890 + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
12891 + luaL_checktype(L, 2, LUA_TFUNCTION);
12892 + lua_settop(L, 2); /* make sure there is two arguments */
12893 + auxsort(L, 1, n);
12897 +/* }====================================================== */
12900 +static const luaL_Reg tab_funcs[] = {
12901 + {"concat", tconcat},
12902 + {"foreach", foreach},
12903 + {"foreachi", foreachi},
12906 + {"insert", tinsert},
12907 + {"remove", tremove},
12914 +LUALIB_API int luaopen_table (lua_State *L) {
12915 + luaL_register(L, LUA_TABLIBNAME, tab_funcs);
12919 +++ b/extensions/LUA/lua/ltm.c
12922 +** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
12924 +** See Copyright Notice in lua.h
12927 +#include <string.h>
12934 +#include "lobject.h"
12935 +#include "lstate.h"
12936 +#include "lstring.h"
12937 +#include "ltable.h"
12942 +const char *const luaT_typenames[] = {
12943 + "nil", "boolean", "userdata", "number",
12944 + "string", "table", "function", "userdata", "thread",
12949 +void luaT_init (lua_State *L) {
12950 + static const char *const luaT_eventname[] = { /* ORDER TM */
12951 + "__index", "__newindex",
12952 + "__gc", "__mode", "__eq",
12953 + "__add", "__sub", "__mul", "__div", "__mod",
12954 + "__pow", "__unm", "__len", "__lt", "__le",
12955 + "__concat", "__call"
12958 + for (i=0; i<TM_N; i++) {
12959 + G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
12960 + luaS_fix(G(L)->tmname[i]); /* never collect these names */
12966 +** function to be used with macro "fasttm": optimized for absence of
12969 +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
12970 + const TValue *tm = luaH_getstr(events, ename);
12971 + lua_assert(event <= TM_EQ);
12972 + if (ttisnil(tm)) { /* no tag method? */
12973 + events->flags |= cast_byte(1u<<event); /* cache this fact */
12980 +const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
12982 + switch (ttype(o)) {
12984 + mt = hvalue(o)->metatable;
12986 + case LUA_TUSERDATA:
12987 + mt = uvalue(o)->metatable;
12990 + mt = G(L)->mt[ttype(o)];
12992 + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
12996 +++ b/extensions/LUA/lua/ltm.h
12999 +** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
13001 +** See Copyright Notice in lua.h
13008 +#include "lobject.h"
13012 +* WARNING: if you change the order of this enumeration,
13020 + TM_EQ, /* last tag method with `fast' access */
13033 + TM_N /* number of elements in the enum */
13038 +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
13039 + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
13041 +#define fasttm(l,et,e) gfasttm(G(l), et, e)
13043 +LUAI_DATA const char *const luaT_typenames[];
13046 +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
13047 +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
13049 +LUAI_FUNC void luaT_init (lua_State *L);
13053 +++ b/extensions/LUA/lua/luaconf.h
13056 +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $
13057 +** Configuration file for Lua
13058 +** See Copyright Notice in lua.h
13065 +#include <stddef.h>
13067 +#if !defined(__KERNEL__)
13068 +#include <limits.h>
13070 +#define UCHAR_MAX 255
13071 +#define SHRT_MAX 32767
13072 +#define BUFSIZ 8192
13077 +** ==================================================================
13078 +** Search for "@@" to find all configurable definitions.
13079 +** ===================================================================
13084 +@@ LUA_ANSI controls the use of non-ansi features.
13085 +** CHANGE it (define it) if you want Lua to avoid the use of any
13086 +** non-ansi feature or library.
13088 +#if defined(__STRICT_ANSI__)
13093 +#if !defined(LUA_ANSI) && defined(_WIN32)
13097 +#if defined(LUA_USE_LINUX)
13098 +#define LUA_USE_POSIX
13099 +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
13100 +#define LUA_USE_READLINE /* needs some extra libraries */
13103 +#if defined(LUA_USE_MACOSX)
13104 +#define LUA_USE_POSIX
13105 +#define LUA_DL_DYLD /* does not need extra library */
13111 +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
13112 +@* Interfaces Extension (XSI).
13113 +** CHANGE it (define it) if your system is XSI compatible.
13115 +#if defined(LUA_USE_POSIX)
13116 +#define LUA_USE_MKSTEMP
13117 +#define LUA_USE_ISATTY
13118 +#define LUA_USE_POPEN
13119 +#define LUA_USE_ULONGJMP
13124 +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
13125 +@* Lua check to set its paths.
13126 +@@ LUA_INIT is the name of the environment variable that Lua
13127 +@* checks for initialization code.
13128 +** CHANGE them if you want different names.
13130 +#define LUA_PATH "LUA_PATH"
13131 +#define LUA_CPATH "LUA_CPATH"
13132 +#define LUA_INIT "LUA_INIT"
13136 +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
13138 +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
13140 +** CHANGE them if your machine has a non-conventional directory
13141 +** hierarchy or if you want to install your libraries in
13142 +** non-conventional directories.
13144 +#if defined(_WIN32)
13146 +** In Windows, any exclamation mark ('!') in the path is replaced by the
13147 +** path of the directory of the executable file of the current process.
13149 +#define LUA_LDIR "!\\lua\\"
13150 +#define LUA_CDIR "!\\"
13151 +#define LUA_PATH_DEFAULT \
13152 + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
13153 + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
13154 +#define LUA_CPATH_DEFAULT \
13155 + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
13158 +#define LUA_ROOT "/usr/local/"
13159 +#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
13160 +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
13161 +#define LUA_PATH_DEFAULT \
13162 + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
13163 + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
13164 +#define LUA_CPATH_DEFAULT \
13165 + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
13170 +@@ LUA_DIRSEP is the directory separator (for submodules).
13171 +** CHANGE it if your machine does not use "/" as the directory separator
13172 +** and is not Windows. (On Windows Lua automatically uses "\".)
13174 +#if defined(_WIN32)
13175 +#define LUA_DIRSEP "\\"
13177 +#define LUA_DIRSEP "/"
13182 +@@ LUA_PATHSEP is the character that separates templates in a path.
13183 +@@ LUA_PATH_MARK is the string that marks the substitution points in a
13185 +@@ LUA_EXECDIR in a Windows path is replaced by the executable's
13187 +@@ LUA_IGMARK is a mark to ignore all before it when bulding the
13188 +@* luaopen_ function name.
13189 +** CHANGE them if for some reason your system cannot use those
13190 +** characters. (E.g., if one of those characters is a common character
13191 +** in file/directory names.) Probably you do not need to change them.
13193 +#define LUA_PATHSEP ";"
13194 +#define LUA_PATH_MARK "?"
13195 +#define LUA_EXECDIR "!"
13196 +#define LUA_IGMARK "-"
13200 +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
13201 +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
13202 +** machines, ptrdiff_t gives a good choice between int or long.)
13204 +#define LUA_INTEGER ptrdiff_t
13208 +@@ LUA_API is a mark for all core API functions.
13209 +@@ LUALIB_API is a mark for all standard library functions.
13210 +** CHANGE them if you need to define those functions in some special way.
13211 +** For instance, if you want to create one Windows DLL with the core and
13212 +** the libraries, you may want to use the following definition (define
13213 +** LUA_BUILD_AS_DLL to get it).
13215 +#if defined(LUA_BUILD_AS_DLL)
13217 +#if defined(LUA_CORE) || defined(LUA_LIB)
13218 +#define LUA_API __declspec(dllexport)
13220 +#define LUA_API __declspec(dllimport)
13225 +#define LUA_API extern
13229 +/* more often than not the libs go together with the core */
13230 +#define LUALIB_API LUA_API
13234 +@@ LUAI_FUNC is a mark for all extern functions that are not to be
13235 +@* exported to outside modules.
13236 +@@ LUAI_DATA is a mark for all extern (const) variables that are not to
13237 +@* be exported to outside modules.
13238 +** CHANGE them if you need to mark them in some special way. Elf/gcc
13239 +** (versions 3.2 and later) mark them as "hidden" to optimize access
13240 +** when Lua is compiled as a shared library.
13242 +#if defined(luaall_c)
13243 +#define LUAI_FUNC static
13244 +#define LUAI_DATA /* empty */
13246 +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
13248 +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
13249 +#define LUAI_DATA LUAI_FUNC
13252 +#define LUAI_FUNC extern
13253 +#define LUAI_DATA extern
13259 +@@ LUA_QL describes how error messages quote program elements.
13260 +** CHANGE it if you want a different appearance.
13262 +#define LUA_QL(x) "'" x "'"
13263 +#define LUA_QS LUA_QL("%s")
13267 +@@ LUA_IDSIZE gives the maximum size for the description of the source
13268 +@* of a function in debug information.
13269 +** CHANGE it if you want a different size.
13271 +#define LUA_IDSIZE 60
13275 +** {==================================================================
13276 +** Stand-alone configuration
13277 +** ===================================================================
13280 +#if defined(lua_c) || defined(luaall_c)
13283 +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
13284 +@* is, whether we're running lua interactively).
13285 +** CHANGE it if you have a better definition for non-POSIX/non-Windows
13288 +#if defined(LUA_USE_ISATTY)
13289 +#include <unistd.h>
13290 +#define lua_stdin_is_tty() isatty(0)
13291 +#elif defined(LUA_WIN)
13293 +#include <stdio.h>
13294 +#define lua_stdin_is_tty() _isatty(_fileno(stdin))
13296 +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
13301 +@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
13302 +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
13303 +** CHANGE them if you want different prompts. (You can also change the
13304 +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
13306 +#define LUA_PROMPT "> "
13307 +#define LUA_PROMPT2 ">> "
13311 +@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
13312 +** CHANGE it if your stand-alone interpreter has a different name and
13313 +** your system is not able to detect that name automatically.
13315 +#define LUA_PROGNAME "lua"
13319 +@@ LUA_MAXINPUT is the maximum length for an input line in the
13320 +@* stand-alone interpreter.
13321 +** CHANGE it if you need longer lines.
13323 +#define LUA_MAXINPUT 512
13327 +@@ lua_readline defines how to show a prompt and then read a line from
13328 +@* the standard input.
13329 +@@ lua_saveline defines how to "save" a read line in a "history".
13330 +@@ lua_freeline defines how to free a line read by lua_readline.
13331 +** CHANGE them if you want to improve this functionality (e.g., by using
13332 +** GNU readline and history facilities).
13334 +#if defined(LUA_USE_READLINE)
13335 +#include <stdio.h>
13336 +#include <readline/readline.h>
13337 +#include <readline/history.h>
13338 +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
13339 +#define lua_saveline(L,idx) \
13340 + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
13341 + add_history(lua_tostring(L, idx)); /* add it to history */
13342 +#define lua_freeline(L,b) ((void)L, free(b))
13344 +#define lua_readline(L,b,p) \
13345 + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
13346 + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
13347 +#define lua_saveline(L,idx) { (void)L; (void)idx; }
13348 +#define lua_freeline(L,b) { (void)L; (void)b; }
13353 +/* }================================================================== */
13357 +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
13358 +@* as a percentage.
13359 +** CHANGE it if you want the GC to run faster or slower (higher values
13360 +** mean larger pauses which mean slower collection.) You can also change
13361 +** this value dynamically.
13363 +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
13367 +@@ LUAI_GCMUL defines the default speed of garbage collection relative to
13368 +@* memory allocation as a percentage.
13369 +** CHANGE it if you want to change the granularity of the garbage
13370 +** collection. (Higher values mean coarser collections. 0 represents
13371 +** infinity, where each step performs a full collection.) You can also
13372 +** change this value dynamically.
13374 +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
13379 +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
13380 +** CHANGE it (define it) if you want exact compatibility with the
13381 +** behavior of setn/getn in Lua 5.0.
13383 +#undef LUA_COMPAT_GETN
13386 +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
13387 +** CHANGE it to undefined as soon as you do not need a global 'loadlib'
13388 +** function (the function is still available as 'package.loadlib').
13390 +#undef LUA_COMPAT_LOADLIB
13393 +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
13394 +** CHANGE it to undefined as soon as your programs use only '...' to
13395 +** access vararg parameters (instead of the old 'arg' table).
13397 +#define LUA_COMPAT_VARARG
13400 +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
13401 +** CHANGE it to undefined as soon as your programs use 'math.fmod' or
13402 +** the new '%' operator instead of 'math.mod'.
13404 +#define LUA_COMPAT_MOD
13407 +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
13409 +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
13410 +** off the advisory error when nesting [[...]].
13412 +#define LUA_COMPAT_LSTR 1
13415 +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
13416 +** CHANGE it to undefined as soon as you rename 'string.gfind' to
13417 +** 'string.gmatch'.
13419 +#define LUA_COMPAT_GFIND
13422 +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
13424 +** CHANGE it to undefined as soon as you replace to 'luaL_register'
13425 +** your uses of 'luaL_openlib'
13427 +#define LUA_COMPAT_OPENLIB
13432 +@@ luai_apicheck is the assert macro used by the Lua-C API.
13433 +** CHANGE luai_apicheck if you want Lua to perform some checks in the
13434 +** parameters it gets from API calls. This may slow down the interpreter
13435 +** a bit, but may be quite useful when debugging C code that interfaces
13436 +** with Lua. A useful redefinition is to use assert.h.
13438 +#if defined(LUA_USE_APICHECK)
13439 +#include <assert.h>
13440 +#define luai_apicheck(L,o) { (void)L; assert(o); }
13442 +#define luai_apicheck(L,o) { (void)L; }
13447 +@@ LUAI_BITSINT defines the number of bits in an int.
13448 +** CHANGE here if Lua cannot automatically detect the number of bits of
13449 +** your machine. Probably you do not need to change this.
13451 +/* avoid overflows in comparison */
13452 +#if !defined(__KERNEL__)
13453 +#include <limits.h>
13454 +#define LUA_INT_MAX INT_MAX
13456 +#define LUA_INT_MAX (~0U>>1)
13459 +#if LUA_INT_MAX-20 < 32760
13460 +#define LUAI_BITSINT 16
13461 +#elif LUA_INT_MAX > 2147483640L
13462 +/* int has at least 32 bits */
13463 +#define LUAI_BITSINT 32
13465 +#error "you must define LUA_BITSINT with number of bits in an integer"
13470 +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
13471 +@@ LUAI_INT32 is an signed integer with at least 32 bits.
13472 +@@ LUAI_UMEM is an unsigned integer big enough to count the total
13473 +@* memory used by Lua.
13474 +@@ LUAI_MEM is a signed integer big enough to count the total memory
13476 +** CHANGE here if for some weird reason the default definitions are not
13477 +** good enough for your machine. (The definitions in the 'else'
13478 +** part always works, but may waste space on machines with 64-bit
13479 +** longs.) Probably you do not need to change this.
13481 +#if LUAI_BITSINT >= 32
13482 +#define LUAI_UINT32 unsigned int
13483 +#define LUAI_INT32 int
13484 +#define LUAI_MAXINT32 INT_MAX
13485 +#define LUAI_UMEM size_t
13486 +#define LUAI_MEM ptrdiff_t
13489 +#define LUAI_UINT32 unsigned long
13490 +#define LUAI_INT32 long
13491 +#define LUAI_MAXINT32 LONG_MAX
13492 +#define LUAI_UMEM unsigned long
13493 +#define LUAI_MEM long
13498 +@@ LUAI_MAXCALLS limits the number of nested calls.
13499 +** CHANGE it if you need really deep recursive calls. This limit is
13500 +** arbitrary; its only purpose is to stop infinite recursion before
13501 +** exhausting memory.
13503 +#define LUAI_MAXCALLS 20000
13507 +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
13509 +** CHANGE it if you need lots of (Lua) stack space for your C
13510 +** functions. This limit is arbitrary; its only purpose is to stop C
13511 +** functions to consume unlimited stack space. (must be smaller than
13512 +** -LUA_REGISTRYINDEX)
13514 +#define LUAI_MAXCSTACK 8000
13519 +** {==================================================================
13520 +** CHANGE (to smaller values) the following definitions if your system
13521 +** has a small C stack. (Or you may want to change them to larger
13522 +** values if your system has a large C stack and these limits are
13523 +** too rigid for you.) Some of these constants control the size of
13524 +** stack-allocated arrays used by the compiler or the interpreter, while
13525 +** others limit the maximum number of recursive calls that the compiler
13526 +** or the interpreter can perform. Values too large may cause a C stack
13527 +** overflow for some forms of deep constructs.
13528 +** ===================================================================
13533 +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
13534 +@* syntactical nested non-terminals in a program.
13536 +#define LUAI_MAXCCALLS 200
13540 +@@ LUAI_MAXVARS is the maximum number of local variables per function
13541 +@* (must be smaller than 250).
13543 +#define LUAI_MAXVARS 200
13547 +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
13548 +@* (must be smaller than 250).
13550 +#define LUAI_MAXUPVALUES 60
13554 +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
13556 +#define LUAL_BUFFERSIZE BUFSIZ
13558 +/* }================================================================== */
13564 +** {==================================================================
13565 +@@ LUA_NUMBER is the type of numbers in Lua.
13566 +** CHANGE the following definitions only if you want to build Lua
13567 +** with a number type different from double. You may also need to
13568 +** change lua_number2int & lua_number2integer.
13569 +** ===================================================================
13571 +#if !defined(NO_FPU)
13572 +#define LUA_NUMBER_DOUBLE
13573 +#define LUA_NUMBER double
13575 +#define LUA_NUMBER long
13579 +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
13582 +#define LUAI_UACNUMBER LUA_NUMBER
13586 +@@ LUA_NUMBER_SCAN is the format for reading numbers.
13587 +@@ LUA_NUMBER_FMT is the format for writing numbers.
13588 +@@ lua_number2str converts a number to a string.
13589 +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
13590 +@@ lua_str2number converts a string to a number.
13592 +#if !defined(NO_FPU)
13593 +#define LUA_NUMBER_SCAN "%lf"
13594 +#define LUA_NUMBER_FMT "%.14g"
13595 +#define lua_str2number(s,p) strtod((s), (p))
13597 +#define LUA_NUMBER_SCAN "%ld"
13598 +#define LUA_NUMBER_FMT "%ld"
13599 +#if !defined(__KERNEL__)
13600 +#define lua_str2number(s,p) strtol((s), (p), 10)
13602 +#define lua_str2number(s,p) simple_strtol((s), (p), 10)
13606 +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
13607 +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
13610 +@@ The luai_num* macros define the primitive operations over numbers.
13612 +#if defined(LUA_CORE)
13613 +#define luai_numadd(a,b) ((a)+(b))
13614 +#define luai_numsub(a,b) ((a)-(b))
13615 +#define luai_nummul(a,b) ((a)*(b))
13616 +#define luai_numdiv(a,b) ((a)/(b))
13617 +#define luai_numunm(a) (-(a))
13618 +#define luai_numeq(a,b) ((a)==(b))
13619 +#define luai_numlt(a,b) ((a)<(b))
13620 +#define luai_numle(a,b) ((a)<=(b))
13621 +#define luai_numisnan(a) (!luai_numeq((a), (a)))
13622 +#if !defined(NO_FPU)
13624 +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
13625 +#define luai_numpow(a,b) (pow(a,b))
13627 +#define luai_nummod(a,b) ((a)%(b))
13628 +#define luai_numpow(a,b) luai_nummul(a,b)
13634 +@@ lua_number2int is a macro to convert lua_Number to int.
13635 +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
13636 +** CHANGE them if you know a faster way to convert a lua_Number to
13637 +** int (with any rounding method and without throwing errors) in your
13638 +** system. In Pentium machines, a naive typecast from double to int
13639 +** in C is extremely slow, so any alternative is worth trying.
13642 +/* On a Pentium, resort to a trick */
13643 +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
13644 + (defined(__i386) || defined (_M_IX86) || defined(__i386__))
13646 +/* On a Microsoft compiler, use assembler */
13647 +#if defined(_MSC_VER)
13649 +#define lua_number2int(i,d) __asm fld d __asm fistp i
13650 +#define lua_number2integer(i,n) lua_number2int(i, n)
13652 +/* the next trick should work on any Pentium, but sometimes clashes
13653 + with a DirectX idiosyncrasy */
13656 +union luai_Cast { double l_d; long l_l; };
13657 +#define lua_number2int(i,d) \
13658 + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
13659 +#define lua_number2integer(i,n) lua_number2int(i, n)
13664 +/* this option always works, but may be slow */
13666 +#define lua_number2int(i,d) ((i)=(int)(d))
13667 +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
13671 +/* }================================================================== */
13675 +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
13676 +** CHANGE it if your system requires alignments larger than double. (For
13677 +** instance, if your system supports long doubles and they must be
13678 +** aligned in 16-byte boundaries, then you should add long double in the
13679 +** union.) Probably you do not need to change this.
13681 +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
13685 +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
13686 +** CHANGE them if you prefer to use longjmp/setjmp even with C++
13687 +** or if want/don't to use _longjmp/_setjmp instead of regular
13688 +** longjmp/setjmp. By default, Lua handles errors with exceptions when
13689 +** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
13690 +** and with longjmp/setjmp otherwise.
13692 +#if defined(__KERNEL__)
13693 +#undef LUA_USE_ULONGJMP
13696 +#if defined(__cplusplus)
13697 +/* C++ exceptions */
13698 +#define LUAI_THROW(L,c) throw(c)
13699 +#define LUAI_TRY(L,c,a) try { a } catch(...) \
13700 + { if ((c)->status == 0) (c)->status = -1; }
13701 +#define luai_jmpbuf int /* dummy variable */
13703 +#elif defined(LUA_USE_ULONGJMP)
13704 +/* in Unix, try _longjmp/_setjmp (more efficient) */
13705 +#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
13706 +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
13707 +#define luai_jmpbuf jmp_buf
13710 +/* default handling with long jumps */
13711 +#define LUAI_THROW(L,c) longjmp((c)->b, 1)
13712 +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
13713 +#define luai_jmpbuf jmp_buf
13719 +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
13720 +@* can do during pattern-matching.
13721 +** CHANGE it if you need more captures. This limit is arbitrary.
13723 +#define LUA_MAXCAPTURES 32
13727 +@@ lua_tmpnam is the function that the OS library uses to create a
13728 +@* temporary name.
13729 +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
13730 +** CHANGE them if you have an alternative to tmpnam (which is considered
13731 +** insecure) or if you want the original tmpnam anyway. By default, Lua
13732 +** uses tmpnam except when POSIX is available, where it uses mkstemp.
13734 +#if defined(loslib_c) || defined(luaall_c)
13736 +#if defined(LUA_USE_MKSTEMP)
13737 +#include <unistd.h>
13738 +#define LUA_TMPNAMBUFSIZE 32
13739 +#define lua_tmpnam(b,e) { \
13740 + strcpy(b, "/tmp/lua_XXXXXX"); \
13741 + e = mkstemp(b); \
13742 + if (e != -1) close(e); \
13746 +#define LUA_TMPNAMBUFSIZE L_tmpnam
13747 +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
13754 +@@ lua_popen spawns a new process connected to the current one through
13755 +@* the file streams.
13756 +** CHANGE it if you have a way to implement it in your system.
13758 +#if defined(LUA_USE_POPEN)
13760 +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
13761 +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
13763 +#elif defined(LUA_WIN)
13765 +#define lua_popen(L,c,m) ((void)L, _popen(c,m))
13766 +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
13770 +#define lua_popen(L,c,m) ((void)((void)c, m), \
13771 + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
13772 +#define lua_pclose(L,file) ((void)((void)L, file), 0)
13777 +@@ LUA_DL_* define which dynamic-library system Lua should use.
13778 +** CHANGE here if Lua has problems choosing the appropriate
13779 +** dynamic-library system for your platform (either Windows' DLL, Mac's
13780 +** dyld, or Unix's dlopen). If your system is some kind of Unix, there
13781 +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
13782 +** it. To use dlopen you also need to adapt the src/Makefile (probably
13783 +** adding -ldl to the linker options), so Lua does not select it
13784 +** automatically. (When you change the makefile to add -ldl, you must
13785 +** also add -DLUA_USE_DLOPEN.)
13786 +** If you do not want any kind of dynamic library, undefine all these
13788 +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
13790 +#if defined(LUA_USE_DLOPEN)
13791 +#define LUA_DL_DLOPEN
13794 +#if defined(LUA_WIN)
13795 +#define LUA_DL_DLL
13800 +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
13801 +@* (the data goes just *before* the lua_State pointer).
13802 +** CHANGE (define) this if you really need that. This value must be
13803 +** a multiple of the maximum alignment required for your machine.
13805 +#define LUAI_EXTRASPACE 0
13809 +@@ luai_userstate* allow user-specific actions on threads.
13810 +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
13811 +** extra when a thread is created/deleted/resumed/yielded.
13813 +#define luai_userstateopen(L) ((void)L)
13814 +#define luai_userstateclose(L) ((void)L)
13815 +#define luai_userstatethread(L,L1) ((void)L)
13816 +#define luai_userstatefree(L) ((void)L)
13817 +#define luai_userstateresume(L,n) ((void)L)
13818 +#define luai_userstateyield(L,n) ((void)L)
13822 +@@ LUA_INTFRMLEN is the length modifier for integer conversions
13823 +@* in 'string.format'.
13824 +@@ LUA_INTFRM_T is the integer type correspoding to the previous length
13826 +** CHANGE them if your system supports long long or does not support long.
13829 +#if defined(LUA_USELONGLONG)
13831 +#define LUA_INTFRMLEN "ll"
13832 +#define LUA_INTFRM_T long long
13836 +#define LUA_INTFRMLEN "l"
13837 +#define LUA_INTFRM_T long
13841 +/* =================================================================== */
13844 +** Local configuration. You can use this space to add your redefinitions
13845 +** without modifying the main part of the file.
13853 +++ b/extensions/LUA/lua/lua.h
13856 +** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
13857 +** Lua - An Extensible Extension Language
13858 +** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
13859 +** See Copyright Notice at the end of this file
13866 +#include <stdarg.h>
13867 +#include <stddef.h>
13869 +#include "luaconf.h"
13872 +#define LUA_VERSION "Lua 5.1"
13873 +#define LUA_RELEASE "Lua 5.1.4"
13874 +#define LUA_VERSION_NUM 501
13875 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
13876 +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
13879 +/* mark for precompiled code (`<esc>Lua') */
13880 +#define LUA_SIGNATURE "\033Lua"
13882 +/* option for multiple returns in `lua_pcall' and `lua_call' */
13883 +#define LUA_MULTRET (-1)
13889 +#define LUA_REGISTRYINDEX (-10000)
13890 +#define LUA_ENVIRONINDEX (-10001)
13891 +#define LUA_GLOBALSINDEX (-10002)
13892 +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
13895 +/* thread status; 0 is OK */
13896 +#define LUA_YIELD 1
13897 +#define LUA_ERRRUN 2
13898 +#define LUA_ERRSYNTAX 3
13899 +#define LUA_ERRMEM 4
13900 +#define LUA_ERRERR 5
13903 +typedef struct lua_State lua_State;
13905 +typedef int (*lua_CFunction) (lua_State *L);
13909 +** functions that read/write blocks when loading/dumping Lua chunks
13911 +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
13913 +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
13917 +** prototype for memory-allocation functions
13919 +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
13925 +#define LUA_TNONE (-1)
13927 +#define LUA_TNIL 0
13928 +#define LUA_TBOOLEAN 1
13929 +#define LUA_TLIGHTUSERDATA 2
13930 +#define LUA_TNUMBER 3
13931 +#define LUA_TSTRING 4
13932 +#define LUA_TTABLE 5
13933 +#define LUA_TFUNCTION 6
13934 +#define LUA_TUSERDATA 7
13935 +#define LUA_TTHREAD 8
13939 +/* minimum Lua stack available to a C function */
13940 +#define LUA_MINSTACK 20
13944 +** generic extra include file
13946 +#if defined(LUA_USER_H)
13947 +#include LUA_USER_H
13951 +/* type of numbers in Lua */
13952 +typedef LUA_NUMBER lua_Number;
13955 +/* type for integer functions */
13956 +typedef LUA_INTEGER lua_Integer;
13961 +** state manipulation
13963 +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
13964 +LUA_API void (lua_close) (lua_State *L);
13965 +LUA_API lua_State *(lua_newthread) (lua_State *L);
13967 +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
13971 +** basic stack manipulation
13973 +LUA_API int (lua_gettop) (lua_State *L);
13974 +LUA_API void (lua_settop) (lua_State *L, int idx);
13975 +LUA_API void (lua_pushvalue) (lua_State *L, int idx);
13976 +LUA_API void (lua_remove) (lua_State *L, int idx);
13977 +LUA_API void (lua_insert) (lua_State *L, int idx);
13978 +LUA_API void (lua_replace) (lua_State *L, int idx);
13979 +LUA_API int (lua_checkstack) (lua_State *L, int sz);
13981 +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
13985 +** access functions (stack -> C)
13988 +LUA_API int (lua_isnumber) (lua_State *L, int idx);
13989 +LUA_API int (lua_isstring) (lua_State *L, int idx);
13990 +LUA_API int (lua_iscfunction) (lua_State *L, int idx);
13991 +LUA_API int (lua_isuserdata) (lua_State *L, int idx);
13992 +LUA_API int (lua_type) (lua_State *L, int idx);
13993 +LUA_API const char *(lua_typename) (lua_State *L, int tp);
13995 +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
13996 +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
13997 +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
13999 +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
14000 +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
14001 +LUA_API int (lua_toboolean) (lua_State *L, int idx);
14002 +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
14003 +LUA_API size_t (lua_objlen) (lua_State *L, int idx);
14004 +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
14005 +LUA_API void *(lua_touserdata) (lua_State *L, int idx);
14006 +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
14007 +LUA_API const void *(lua_topointer) (lua_State *L, int idx);
14011 +** push functions (C -> stack)
14013 +LUA_API void (lua_pushnil) (lua_State *L);
14014 +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
14015 +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
14016 +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
14017 +LUA_API void (lua_pushstring) (lua_State *L, const char *s);
14018 +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
14020 +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
14021 +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
14022 +LUA_API void (lua_pushboolean) (lua_State *L, int b);
14023 +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
14024 +LUA_API int (lua_pushthread) (lua_State *L);
14028 +** get functions (Lua -> stack)
14030 +LUA_API void (lua_gettable) (lua_State *L, int idx);
14031 +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
14032 +LUA_API void (lua_rawget) (lua_State *L, int idx);
14033 +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
14034 +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
14035 +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
14036 +LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
14037 +LUA_API void (lua_getfenv) (lua_State *L, int idx);
14041 +** set functions (stack -> Lua)
14043 +LUA_API void (lua_settable) (lua_State *L, int idx);
14044 +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
14045 +LUA_API void (lua_rawset) (lua_State *L, int idx);
14046 +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
14047 +LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
14048 +LUA_API int (lua_setfenv) (lua_State *L, int idx);
14052 +** `load' and `call' functions (load and run Lua code)
14054 +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
14055 +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
14056 +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
14057 +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
14058 + const char *chunkname);
14060 +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
14064 +** coroutine functions
14066 +LUA_API int (lua_yield) (lua_State *L, int nresults);
14067 +LUA_API int (lua_resume) (lua_State *L, int narg);
14068 +LUA_API int (lua_status) (lua_State *L);
14071 +** garbage-collection function and options
14074 +#define LUA_GCSTOP 0
14075 +#define LUA_GCRESTART 1
14076 +#define LUA_GCCOLLECT 2
14077 +#define LUA_GCCOUNT 3
14078 +#define LUA_GCCOUNTB 4
14079 +#define LUA_GCSTEP 5
14080 +#define LUA_GCSETPAUSE 6
14081 +#define LUA_GCSETSTEPMUL 7
14083 +LUA_API int (lua_gc) (lua_State *L, int what, int data);
14087 +** miscellaneous functions
14090 +LUA_API int (lua_error) (lua_State *L);
14092 +LUA_API int (lua_next) (lua_State *L, int idx);
14094 +LUA_API void (lua_concat) (lua_State *L, int n);
14096 +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
14097 +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
14102 +** ===============================================================
14103 +** some useful macros
14104 +** ===============================================================
14107 +#define lua_pop(L,n) lua_settop(L, -(n)-1)
14109 +#define lua_newtable(L) lua_createtable(L, 0, 0)
14111 +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
14113 +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
14115 +#define lua_strlen(L,i) lua_objlen(L, (i))
14117 +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
14118 +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
14119 +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
14120 +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
14121 +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
14122 +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
14123 +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
14124 +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
14126 +#define lua_pushliteral(L, s) \
14127 + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
14129 +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
14130 +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
14132 +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
14137 +** compatibility macros and functions
14140 +#define lua_open() luaL_newstate()
14142 +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
14144 +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
14146 +#define lua_Chunkreader lua_Reader
14147 +#define lua_Chunkwriter lua_Writer
14151 +LUA_API void lua_setlevel (lua_State *from, lua_State *to);
14155 +** {======================================================================
14157 +** =======================================================================
14164 +#define LUA_HOOKCALL 0
14165 +#define LUA_HOOKRET 1
14166 +#define LUA_HOOKLINE 2
14167 +#define LUA_HOOKCOUNT 3
14168 +#define LUA_HOOKTAILRET 4
14174 +#define LUA_MASKCALL (1 << LUA_HOOKCALL)
14175 +#define LUA_MASKRET (1 << LUA_HOOKRET)
14176 +#define LUA_MASKLINE (1 << LUA_HOOKLINE)
14177 +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
14179 +typedef struct lua_Debug lua_Debug; /* activation record */
14182 +/* Functions to be called by the debuger in specific events */
14183 +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
14186 +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
14187 +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
14188 +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
14189 +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
14190 +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
14191 +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
14193 +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
14194 +LUA_API lua_Hook lua_gethook (lua_State *L);
14195 +LUA_API int lua_gethookmask (lua_State *L);
14196 +LUA_API int lua_gethookcount (lua_State *L);
14199 +struct lua_Debug {
14201 + const char *name; /* (n) */
14202 + const char *namewhat; /* (n) `global', `local', `field', `method' */
14203 + const char *what; /* (S) `Lua', `C', `main', `tail' */
14204 + const char *source; /* (S) */
14205 + int currentline; /* (l) */
14206 + int nups; /* (u) number of upvalues */
14207 + int linedefined; /* (S) */
14208 + int lastlinedefined; /* (S) */
14209 + char short_src[LUA_IDSIZE]; /* (S) */
14210 + /* private part */
14211 + int i_ci; /* active function */
14214 +/* }====================================================================== */
14217 +/******************************************************************************
14218 +* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
14220 +* Permission is hereby granted, free of charge, to any person obtaining
14221 +* a copy of this software and associated documentation files (the
14222 +* "Software"), to deal in the Software without restriction, including
14223 +* without limitation the rights to use, copy, modify, merge, publish,
14224 +* distribute, sublicense, and/or sell copies of the Software, and to
14225 +* permit persons to whom the Software is furnished to do so, subject to
14226 +* the following conditions:
14228 +* The above copyright notice and this permission notice shall be
14229 +* included in all copies or substantial portions of the Software.
14231 +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14232 +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14233 +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
14234 +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
14235 +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
14236 +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
14237 +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14238 +******************************************************************************/
14243 +++ b/extensions/LUA/lua/lualib.h
14246 +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
14247 +** Lua standard libraries
14248 +** See Copyright Notice in lua.h
14258 +/* Key to file-handle type */
14259 +#define LUA_FILEHANDLE "FILE*"
14262 +#define LUA_COLIBNAME "coroutine"
14263 +LUALIB_API int (luaopen_base) (lua_State *L);
14265 +#define LUA_TABLIBNAME "table"
14266 +LUALIB_API int (luaopen_table) (lua_State *L);
14268 +#define LUA_IOLIBNAME "io"
14269 +LUALIB_API int (luaopen_io) (lua_State *L);
14271 +#define LUA_OSLIBNAME "os"
14272 +LUALIB_API int (luaopen_os) (lua_State *L);
14275 +#define LUA_STRLIBNAME "string"
14276 +LUALIB_API int (luaopen_string) (lua_State *L);
14279 +#define LUA_MATHLIBNAME "math"
14280 +LUALIB_API int (luaopen_math) (lua_State *L);
14282 +#define LUA_DBLIBNAME "debug"
14283 +LUALIB_API int (luaopen_debug) (lua_State *L);
14285 +#define LUA_LOADLIBNAME "package"
14286 +LUALIB_API int (luaopen_package) (lua_State *L);
14289 +/* open all previous libraries */
14290 +LUALIB_API void (luaL_openlibs) (lua_State *L);
14294 +#ifndef lua_assert
14295 +#define lua_assert(x) ((void)0)
14301 +++ b/extensions/LUA/lua/lundump.c
14304 +** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
14305 +** load precompiled Lua chunks
14306 +** See Copyright Notice in lua.h
14309 +#include <string.h>
14316 +#include "ldebug.h"
14318 +#include "lfunc.h"
14320 +#include "lobject.h"
14321 +#include "lstring.h"
14322 +#include "lundump.h"
14329 + const char* name;
14332 +#ifdef LUAC_TRUST_BINARIES
14334 +#define error(S,s)
14336 +#define IF(c,s) if (c) error(S,s)
14338 +static void error(LoadState* S, const char* why)
14340 + luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
14341 + luaD_throw(S->L,LUA_ERRSYNTAX);
14345 +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
14346 +#define LoadByte(S) (lu_byte)LoadChar(S)
14347 +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
14348 +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
14350 +static void LoadBlock(LoadState* S, void* b, size_t size)
14352 + size_t r=luaZ_read(S->Z,b,size);
14353 + IF (r!=0, "unexpected end");
14356 +static int LoadChar(LoadState* S)
14363 +static int LoadInt(LoadState* S)
14367 + IF (x<0, "bad integer");
14371 +static lua_Number LoadNumber(LoadState* S)
14378 +static TString* LoadString(LoadState* S)
14386 + char* s=luaZ_openspace(S->L,S->b,size);
14387 + LoadBlock(S,s,size);
14388 + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
14392 +static void LoadCode(LoadState* S, Proto* f)
14394 + int n=LoadInt(S);
14395 + f->code=luaM_newvector(S->L,n,Instruction);
14397 + LoadVector(S,f->code,n,sizeof(Instruction));
14400 +static Proto* LoadFunction(LoadState* S, TString* p);
14402 +static void LoadConstants(LoadState* S, Proto* f)
14406 + f->k=luaM_newvector(S->L,n,TValue);
14408 + for (i=0; i<n; i++) setnilvalue(&f->k[i]);
14409 + for (i=0; i<n; i++)
14411 + TValue* o=&f->k[i];
14412 + int t=LoadChar(S);
14418 + case LUA_TBOOLEAN:
14419 + setbvalue(o,LoadChar(S)!=0);
14421 + case LUA_TNUMBER:
14422 + setnvalue(o,LoadNumber(S));
14424 + case LUA_TSTRING:
14425 + setsvalue2n(S->L,o,LoadString(S));
14428 + error(S,"bad constant");
14433 + f->p=luaM_newvector(S->L,n,Proto*);
14435 + for (i=0; i<n; i++) f->p[i]=NULL;
14436 + for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
14439 +static void LoadDebug(LoadState* S, Proto* f)
14443 + f->lineinfo=luaM_newvector(S->L,n,int);
14444 + f->sizelineinfo=n;
14445 + LoadVector(S,f->lineinfo,n,sizeof(int));
14447 + f->locvars=luaM_newvector(S->L,n,LocVar);
14448 + f->sizelocvars=n;
14449 + for (i=0; i<n; i++) f->locvars[i].varname=NULL;
14450 + for (i=0; i<n; i++)
14452 + f->locvars[i].varname=LoadString(S);
14453 + f->locvars[i].startpc=LoadInt(S);
14454 + f->locvars[i].endpc=LoadInt(S);
14457 + f->upvalues=luaM_newvector(S->L,n,TString*);
14458 + f->sizeupvalues=n;
14459 + for (i=0; i<n; i++) f->upvalues[i]=NULL;
14460 + for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
14463 +static Proto* LoadFunction(LoadState* S, TString* p)
14466 + if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
14467 + f=luaF_newproto(S->L);
14468 + setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
14469 + f->source=LoadString(S); if (f->source==NULL) f->source=p;
14470 + f->linedefined=LoadInt(S);
14471 + f->lastlinedefined=LoadInt(S);
14472 + f->nups=LoadByte(S);
14473 + f->numparams=LoadByte(S);
14474 + f->is_vararg=LoadByte(S);
14475 + f->maxstacksize=LoadByte(S);
14477 + LoadConstants(S,f);
14479 + IF (!luaG_checkcode(f), "bad code");
14485 +static void LoadHeader(LoadState* S)
14487 + char h[LUAC_HEADERSIZE];
14488 + char s[LUAC_HEADERSIZE];
14490 + LoadBlock(S,s,LUAC_HEADERSIZE);
14491 + IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
14495 +** load precompiled chunk
14497 +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
14500 + if (*name=='@' || *name=='=')
14502 + else if (*name==LUA_SIGNATURE[0])
14503 + S.name="binary string";
14510 + return LoadFunction(&S,luaS_newliteral(L,"=?"));
14516 +void luaU_header (char* h)
14519 + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
14520 + h+=sizeof(LUA_SIGNATURE)-1;
14521 + *h++=(char)LUAC_VERSION;
14522 + *h++=(char)LUAC_FORMAT;
14523 + *h++=(char)*(char*)&x; /* endianness */
14524 + *h++=(char)sizeof(int);
14525 + *h++=(char)sizeof(size_t);
14526 + *h++=(char)sizeof(Instruction);
14527 + *h++=(char)sizeof(lua_Number);
14528 + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
14531 +++ b/extensions/LUA/lua/lundump.h
14534 +** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
14535 +** load precompiled Lua chunks
14536 +** See Copyright Notice in lua.h
14542 +#include "lobject.h"
14545 +/* load one chunk; from lundump.c */
14546 +LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
14548 +/* make header; from lundump.c */
14549 +LUAI_FUNC void luaU_header (char* h);
14551 +/* dump one chunk; from ldump.c */
14552 +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
14555 +/* print one chunk; from print.c */
14556 +LUAI_FUNC void luaU_print (const Proto* f, int full);
14559 +/* for header of binary files -- this is Lua 5.1 */
14560 +#define LUAC_VERSION 0x51
14562 +/* for header of binary files -- this is the official format */
14563 +#define LUAC_FORMAT 0
14565 +/* size of header of binary files */
14566 +#define LUAC_HEADERSIZE 12
14570 +++ b/extensions/LUA/lua/lvm.c
14573 +** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $
14574 +** Lua virtual machine
14575 +** See Copyright Notice in lua.h
14578 +#include <stdio.h>
14579 +#include <stdlib.h>
14580 +#include <string.h>
14587 +#include "ldebug.h"
14589 +#include "lfunc.h"
14591 +#include "lobject.h"
14592 +#include "lopcodes.h"
14593 +#include "lstate.h"
14594 +#include "lstring.h"
14595 +#include "ltable.h"
14601 +/* limit for table tag-method chains (to avoid loops) */
14602 +#define MAXTAGLOOP 100
14605 +const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
14607 + if (ttisnumber(obj)) return obj;
14608 + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
14609 + setnvalue(n, num);
14617 +int luaV_tostring (lua_State *L, StkId obj) {
14618 + if (!ttisnumber(obj))
14621 + char s[LUAI_MAXNUMBER2STR];
14622 + lua_Number n = nvalue(obj);
14623 + lua_number2str(s, n);
14624 + setsvalue2s(L, obj, luaS_new(L, s));
14630 +static void traceexec (lua_State *L, const Instruction *pc) {
14631 + lu_byte mask = L->hookmask;
14632 + const Instruction *oldpc = L->savedpc;
14634 + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
14635 + resethookcount(L);
14636 + luaD_callhook(L, LUA_HOOKCOUNT, -1);
14638 + if (mask & LUA_MASKLINE) {
14639 + Proto *p = ci_func(L->ci)->l.p;
14640 + int npc = pcRel(pc, p);
14641 + int newline = getline(p, npc);
14642 + /* call linehook when enter a new function, when jump back (loop),
14643 + or when enter a new line */
14644 + if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
14645 + luaD_callhook(L, LUA_HOOKLINE, newline);
14650 +static void callTMres (lua_State *L, StkId res, const TValue *f,
14651 + const TValue *p1, const TValue *p2) {
14652 + ptrdiff_t result = savestack(L, res);
14653 + setobj2s(L, L->top, f); /* push function */
14654 + setobj2s(L, L->top+1, p1); /* 1st argument */
14655 + setobj2s(L, L->top+2, p2); /* 2nd argument */
14656 + luaD_checkstack(L, 3);
14658 + luaD_call(L, L->top - 3, 1);
14659 + res = restorestack(L, result);
14661 + setobjs2s(L, res, L->top);
14666 +static void callTM (lua_State *L, const TValue *f, const TValue *p1,
14667 + const TValue *p2, const TValue *p3) {
14668 + setobj2s(L, L->top, f); /* push function */
14669 + setobj2s(L, L->top+1, p1); /* 1st argument */
14670 + setobj2s(L, L->top+2, p2); /* 2nd argument */
14671 + setobj2s(L, L->top+3, p3); /* 3th argument */
14672 + luaD_checkstack(L, 4);
14674 + luaD_call(L, L->top - 4, 0);
14678 +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
14680 + for (loop = 0; loop < MAXTAGLOOP; loop++) {
14681 + const TValue *tm;
14682 + if (ttistable(t)) { /* `t' is a table? */
14683 + Table *h = hvalue(t);
14684 + const TValue *res = luaH_get(h, key); /* do a primitive get */
14685 + if (!ttisnil(res) || /* result is no nil? */
14686 + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
14687 + setobj2s(L, val, res);
14690 + /* else will try the tag method */
14692 + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
14693 + luaG_typeerror(L, t, "index");
14694 + if (ttisfunction(tm)) {
14695 + callTMres(L, val, tm, t, key);
14698 + t = tm; /* else repeat with `tm' */
14700 + luaG_runerror(L, "loop in gettable");
14704 +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
14706 + for (loop = 0; loop < MAXTAGLOOP; loop++) {
14707 + const TValue *tm;
14708 + if (ttistable(t)) { /* `t' is a table? */
14709 + Table *h = hvalue(t);
14710 + TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
14711 + if (!ttisnil(oldval) || /* result is no nil? */
14712 + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
14713 + setobj2t(L, oldval, val);
14714 + luaC_barriert(L, h, val);
14717 + /* else will try the tag method */
14719 + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
14720 + luaG_typeerror(L, t, "index");
14721 + if (ttisfunction(tm)) {
14722 + callTM(L, tm, t, key, val);
14725 + t = tm; /* else repeat with `tm' */
14727 + luaG_runerror(L, "loop in settable");
14731 +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
14732 + StkId res, TMS event) {
14733 + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
14735 + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
14736 + if (ttisnil(tm)) return 0;
14737 + callTMres(L, res, tm, p1, p2);
14742 +static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
14744 + const TValue *tm1 = fasttm(L, mt1, event);
14745 + const TValue *tm2;
14746 + if (tm1 == NULL) return NULL; /* no metamethod */
14747 + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
14748 + tm2 = fasttm(L, mt2, event);
14749 + if (tm2 == NULL) return NULL; /* no metamethod */
14750 + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
14756 +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
14758 + const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
14759 + const TValue *tm2;
14760 + if (ttisnil(tm1)) return -1; /* no metamethod? */
14761 + tm2 = luaT_gettmbyobj(L, p2, event);
14762 + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
14764 + callTMres(L, L->top, tm1, p1, p2);
14765 + return !l_isfalse(L->top);
14769 +static int l_strcmp (const TString *ls, const TString *rs) {
14770 + const char *l = getstr(ls);
14771 + size_t ll = ls->tsv.len;
14772 + const char *r = getstr(rs);
14773 + size_t lr = rs->tsv.len;
14775 + int temp = strcoll(l, r);
14776 + if (temp != 0) return temp;
14777 + else { /* strings are equal up to a `\0' */
14778 + size_t len = strlen(l); /* index of first `\0' in both strings */
14779 + if (len == lr) /* r is finished? */
14780 + return (len == ll) ? 0 : 1;
14781 + else if (len == ll) /* l is finished? */
14782 + return -1; /* l is smaller than r (because r is not finished) */
14783 + /* both strings longer than `len'; go on comparing (after the `\0') */
14785 + l += len; ll -= len; r += len; lr -= len;
14791 +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
14793 + if (ttype(l) != ttype(r))
14794 + return luaG_ordererror(L, l, r);
14795 + else if (ttisnumber(l))
14796 + return luai_numlt(nvalue(l), nvalue(r));
14797 + else if (ttisstring(l))
14798 + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
14799 + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
14801 + return luaG_ordererror(L, l, r);
14805 +static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
14807 + if (ttype(l) != ttype(r))
14808 + return luaG_ordererror(L, l, r);
14809 + else if (ttisnumber(l))
14810 + return luai_numle(nvalue(l), nvalue(r));
14811 + else if (ttisstring(l))
14812 + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
14813 + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
14815 + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
14817 + return luaG_ordererror(L, l, r);
14821 +int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
14822 + const TValue *tm;
14823 + lua_assert(ttype(t1) == ttype(t2));
14824 + switch (ttype(t1)) {
14825 + case LUA_TNIL: return 1;
14826 + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
14827 + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
14828 + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
14829 + case LUA_TUSERDATA: {
14830 + if (uvalue(t1) == uvalue(t2)) return 1;
14831 + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
14833 + break; /* will try TM */
14835 + case LUA_TTABLE: {
14836 + if (hvalue(t1) == hvalue(t2)) return 1;
14837 + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
14838 + break; /* will try TM */
14840 + default: return gcvalue(t1) == gcvalue(t2);
14842 + if (tm == NULL) return 0; /* no TM? */
14843 + callTMres(L, L->top, tm, t1, t2); /* call TM */
14844 + return !l_isfalse(L->top);
14848 +void luaV_concat (lua_State *L, int total, int last) {
14850 + StkId top = L->base + last + 1;
14851 + int n = 2; /* number of elements handled in this pass (at least 2) */
14852 + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
14853 + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
14854 + luaG_concaterror(L, top-2, top-1);
14855 + } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
14856 + (void)tostring(L, top - 2); /* result is first op (as string) */
14858 + /* at least two string values; get as many as possible */
14859 + size_t tl = tsvalue(top-1)->len;
14862 + /* collect total length */
14863 + for (n = 1; n < total && tostring(L, top-n-1); n++) {
14864 + size_t l = tsvalue(top-n-1)->len;
14865 + if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
14868 + buffer = luaZ_openspace(L, &G(L)->buff, tl);
14870 + for (i=n; i>0; i--) { /* concat all strings */
14871 + size_t l = tsvalue(top-i)->len;
14872 + memcpy(buffer+tl, svalue(top-i), l);
14875 + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
14877 + total -= n-1; /* got `n' strings to create 1 new */
14879 + } while (total > 1); /* repeat until only 1 result left */
14883 +static void Arith (lua_State *L, StkId ra, const TValue *rb,
14884 + const TValue *rc, TMS op) {
14885 + TValue tempb, tempc;
14886 + const TValue *b, *c;
14887 + if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
14888 + (c = luaV_tonumber(rc, &tempc)) != NULL) {
14889 + lua_Number nb = nvalue(b), nc = nvalue(c);
14891 + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
14892 + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
14893 + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
14894 + case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
14895 + case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
14896 + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
14897 + case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
14898 + default: lua_assert(0); break;
14901 + else if (!call_binTM(L, rb, rc, ra, op))
14902 + luaG_aritherror(L, rb, rc);
14908 +** some macros for common tasks in `luaV_execute'
14911 +#define runtime_check(L, c) { if (!(c)) break; }
14913 +#define RA(i) (base+GETARG_A(i))
14914 +/* to be used after possible stack reallocation */
14915 +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
14916 +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
14917 +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
14918 + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
14919 +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
14920 + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
14921 +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
14924 +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
14927 +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
14930 +#define arith_op(op,tm) { \
14931 + TValue *rb = RKB(i); \
14932 + TValue *rc = RKC(i); \
14933 + if (ttisnumber(rb) && ttisnumber(rc)) { \
14934 + lua_Number nb = nvalue(rb), nc = nvalue(rc); \
14935 + setnvalue(ra, op(nb, nc)); \
14938 + Protect(Arith(L, ra, rb, rc, tm)); \
14943 +void luaV_execute (lua_State *L, int nexeccalls) {
14947 + const Instruction *pc;
14948 + reentry: /* entry point */
14949 + lua_assert(isLua(L->ci));
14951 + cl = &clvalue(L->ci->func)->l;
14954 + /* main loop of interpreter */
14956 + const Instruction i = *pc++;
14958 + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
14959 + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
14960 + traceexec(L, pc);
14961 + if (L->status == LUA_YIELD) { /* did hook yield? */
14962 + L->savedpc = pc - 1;
14967 + /* warning!! several calls may realloc the stack and invalidate `ra' */
14969 + lua_assert(base == L->base && L->base == L->ci->base);
14970 + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
14971 + lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
14972 + switch (GET_OPCODE(i)) {
14974 + setobjs2s(L, ra, RB(i));
14978 + setobj2s(L, ra, KBx(i));
14981 + case OP_LOADBOOL: {
14982 + setbvalue(ra, GETARG_B(i));
14983 + if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
14986 + case OP_LOADNIL: {
14987 + TValue *rb = RB(i);
14989 + setnilvalue(rb--);
14990 + } while (rb >= ra);
14993 + case OP_GETUPVAL: {
14994 + int b = GETARG_B(i);
14995 + setobj2s(L, ra, cl->upvals[b]->v);
14998 + case OP_GETGLOBAL: {
15000 + TValue *rb = KBx(i);
15001 + sethvalue(L, &g, cl->env);
15002 + lua_assert(ttisstring(rb));
15003 + Protect(luaV_gettable(L, &g, rb, ra));
15006 + case OP_GETTABLE: {
15007 + Protect(luaV_gettable(L, RB(i), RKC(i), ra));
15010 + case OP_SETGLOBAL: {
15012 + sethvalue(L, &g, cl->env);
15013 + lua_assert(ttisstring(KBx(i)));
15014 + Protect(luaV_settable(L, &g, KBx(i), ra));
15017 + case OP_SETUPVAL: {
15018 + UpVal *uv = cl->upvals[GETARG_B(i)];
15019 + setobj(L, uv->v, ra);
15020 + luaC_barrier(L, uv, ra);
15023 + case OP_SETTABLE: {
15024 + Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
15027 + case OP_NEWTABLE: {
15028 + int b = GETARG_B(i);
15029 + int c = GETARG_C(i);
15030 + sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
15031 + Protect(luaC_checkGC(L));
15035 + StkId rb = RB(i);
15036 + setobjs2s(L, ra+1, rb);
15037 + Protect(luaV_gettable(L, rb, RKC(i), ra));
15041 + arith_op(luai_numadd, TM_ADD);
15045 + arith_op(luai_numsub, TM_SUB);
15049 + arith_op(luai_nummul, TM_MUL);
15053 + arith_op(luai_numdiv, TM_DIV);
15057 + arith_op(luai_nummod, TM_MOD);
15061 + arith_op(luai_numpow, TM_POW);
15065 + TValue *rb = RB(i);
15066 + if (ttisnumber(rb)) {
15067 + lua_Number nb = nvalue(rb);
15068 + setnvalue(ra, luai_numunm(nb));
15071 + Protect(Arith(L, ra, rb, rb, TM_UNM));
15076 + int res = l_isfalse(RB(i)); /* next assignment may change this value */
15077 + setbvalue(ra, res);
15081 + const TValue *rb = RB(i);
15082 + switch (ttype(rb)) {
15083 + case LUA_TTABLE: {
15084 + setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
15087 + case LUA_TSTRING: {
15088 + setnvalue(ra, cast_num(tsvalue(rb)->len));
15091 + default: { /* try metamethod */
15093 + if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
15094 + luaG_typeerror(L, rb, "get length of");
15100 + case OP_CONCAT: {
15101 + int b = GETARG_B(i);
15102 + int c = GETARG_C(i);
15103 + Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
15104 + setobjs2s(L, RA(i), base+b);
15108 + dojump(L, pc, GETARG_sBx(i));
15112 + TValue *rb = RKB(i);
15113 + TValue *rc = RKC(i);
15115 + if (equalobj(L, rb, rc) == GETARG_A(i))
15116 + dojump(L, pc, GETARG_sBx(*pc));
15123 + if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
15124 + dojump(L, pc, GETARG_sBx(*pc));
15131 + if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
15132 + dojump(L, pc, GETARG_sBx(*pc));
15138 + if (l_isfalse(ra) != GETARG_C(i))
15139 + dojump(L, pc, GETARG_sBx(*pc));
15143 + case OP_TESTSET: {
15144 + TValue *rb = RB(i);
15145 + if (l_isfalse(rb) != GETARG_C(i)) {
15146 + setobjs2s(L, ra, rb);
15147 + dojump(L, pc, GETARG_sBx(*pc));
15153 + int b = GETARG_B(i);
15154 + int nresults = GETARG_C(i) - 1;
15155 + if (b != 0) L->top = ra+b; /* else previous instruction set top */
15157 + switch (luaD_precall(L, ra, nresults)) {
15160 + goto reentry; /* restart luaV_execute over new Lua function */
15163 + /* it was a C function (`precall' called it); adjust results */
15164 + if (nresults >= 0) L->top = L->ci->top;
15169 + return; /* yield */
15173 + case OP_TAILCALL: {
15174 + int b = GETARG_B(i);
15175 + if (b != 0) L->top = ra+b; /* else previous instruction set top */
15177 + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
15178 + switch (luaD_precall(L, ra, LUA_MULTRET)) {
15180 + /* tail call: put new frame in place of previous one */
15181 + CallInfo *ci = L->ci - 1; /* previous frame */
15183 + StkId func = ci->func;
15184 + StkId pfunc = (ci+1)->func; /* previous function index */
15185 + if (L->openupval) luaF_close(L, ci->base);
15186 + L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
15187 + for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
15188 + setobjs2s(L, func+aux, pfunc+aux);
15189 + ci->top = L->top = func+aux; /* correct top */
15190 + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
15191 + ci->savedpc = L->savedpc;
15192 + ci->tailcalls++; /* one more call lost */
15193 + L->ci--; /* remove new frame */
15196 + case PCRC: { /* it was a C function (`precall' called it) */
15201 + return; /* yield */
15205 + case OP_RETURN: {
15206 + int b = GETARG_B(i);
15207 + if (b != 0) L->top = ra+b-1;
15208 + if (L->openupval) luaF_close(L, base);
15210 + b = luaD_poscall(L, ra);
15211 + if (--nexeccalls == 0) /* was previous function running `here'? */
15212 + return; /* no: return */
15213 + else { /* yes: continue its execution */
15214 + if (b) L->top = L->ci->top;
15215 + lua_assert(isLua(L->ci));
15216 + lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
15220 + case OP_FORLOOP: {
15221 + lua_Number step = nvalue(ra+2);
15222 + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
15223 + lua_Number limit = nvalue(ra+1);
15224 + if (luai_numlt(0, step) ? luai_numle(idx, limit)
15225 + : luai_numle(limit, idx)) {
15226 + dojump(L, pc, GETARG_sBx(i)); /* jump back */
15227 + setnvalue(ra, idx); /* update internal index... */
15228 + setnvalue(ra+3, idx); /* ...and external index */
15232 + case OP_FORPREP: {
15233 + const TValue *init = ra;
15234 + const TValue *plimit = ra+1;
15235 + const TValue *pstep = ra+2;
15236 + L->savedpc = pc; /* next steps may throw errors */
15237 + if (!tonumber(init, ra))
15238 + luaG_runerror(L, LUA_QL("for") " initial value must be a number");
15239 + else if (!tonumber(plimit, ra+1))
15240 + luaG_runerror(L, LUA_QL("for") " limit must be a number");
15241 + else if (!tonumber(pstep, ra+2))
15242 + luaG_runerror(L, LUA_QL("for") " step must be a number");
15243 + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
15244 + dojump(L, pc, GETARG_sBx(i));
15247 + case OP_TFORLOOP: {
15248 + StkId cb = ra + 3; /* call base */
15249 + setobjs2s(L, cb+2, ra+2);
15250 + setobjs2s(L, cb+1, ra+1);
15251 + setobjs2s(L, cb, ra);
15252 + L->top = cb+3; /* func. + 2 args (state and index) */
15253 + Protect(luaD_call(L, cb, GETARG_C(i)));
15254 + L->top = L->ci->top;
15255 + cb = RA(i) + 3; /* previous call may change the stack */
15256 + if (!ttisnil(cb)) { /* continue loop? */
15257 + setobjs2s(L, cb-1, cb); /* save control variable */
15258 + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
15263 + case OP_SETLIST: {
15264 + int n = GETARG_B(i);
15265 + int c = GETARG_C(i);
15269 + n = cast_int(L->top - ra) - 1;
15270 + L->top = L->ci->top;
15272 + if (c == 0) c = cast_int(*pc++);
15273 + runtime_check(L, ttistable(ra));
15275 + last = ((c-1)*LFIELDS_PER_FLUSH) + n;
15276 + if (last > h->sizearray) /* needs more space? */
15277 + luaH_resizearray(L, h, last); /* pre-alloc it at once */
15278 + for (; n > 0; n--) {
15279 + TValue *val = ra+n;
15280 + setobj2t(L, luaH_setnum(L, h, last--), val);
15281 + luaC_barriert(L, h, val);
15286 + luaF_close(L, ra);
15289 + case OP_CLOSURE: {
15293 + p = cl->p->p[GETARG_Bx(i)];
15295 + ncl = luaF_newLclosure(L, nup, cl->env);
15297 + for (j=0; j<nup; j++, pc++) {
15298 + if (GET_OPCODE(*pc) == OP_GETUPVAL)
15299 + ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
15301 + lua_assert(GET_OPCODE(*pc) == OP_MOVE);
15302 + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
15305 + setclvalue(L, ra, ncl);
15306 + Protect(luaC_checkGC(L));
15309 + case OP_VARARG: {
15310 + int b = GETARG_B(i) - 1;
15312 + CallInfo *ci = L->ci;
15313 + int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
15314 + if (b == LUA_MULTRET) {
15315 + Protect(luaD_checkstack(L, n));
15316 + ra = RA(i); /* previous call may change the stack */
15320 + for (j = 0; j < b; j++) {
15322 + setobjs2s(L, ra + j, ci->base - n + j);
15325 + setnilvalue(ra + j);
15335 +++ b/extensions/LUA/lua/lvm.h
15338 +** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
15339 +** Lua virtual machine
15340 +** See Copyright Notice in lua.h
15348 +#include "lobject.h"
15352 +#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
15354 +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
15355 + (((o) = luaV_tonumber(o,n)) != NULL))
15357 +#define equalobj(L,o1,o2) \
15358 + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
15361 +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
15362 +LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
15363 +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
15364 +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
15365 +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
15367 +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
15369 +LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
15370 +LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
15374 +++ b/extensions/LUA/lua/lzio.c
15377 +** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
15378 +** a generic input stream interface
15379 +** See Copyright Notice in lua.h
15382 +#include <string.h>
15389 +#include "llimits.h"
15391 +#include "lstate.h"
15395 +int luaZ_fill (ZIO *z) {
15397 + lua_State *L = z->L;
15398 + const char *buff;
15400 + buff = z->reader(L, z->data, &size);
15402 + if (buff == NULL || size == 0) return EOZ;
15405 + return char2int(*(z->p++));
15409 +int luaZ_lookahead (ZIO *z) {
15411 + if (luaZ_fill(z) == EOZ)
15414 + z->n++; /* luaZ_fill removed first byte; put back it */
15418 + return char2int(*z->p);
15422 +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
15424 + z->reader = reader;
15431 +/* --------------------------------------------------------------- read --- */
15432 +size_t luaZ_read (ZIO *z, void *b, size_t n) {
15435 + if (luaZ_lookahead(z) == EOZ)
15436 + return n; /* return number of missing bytes */
15437 + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
15438 + memcpy(b, z->p, m);
15441 + b = (char *)b + m;
15447 +/* ------------------------------------------------------------------------ */
15448 +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
15449 + if (n > buff->buffsize) {
15450 + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
15451 + luaZ_resizebuffer(L, buff, n);
15453 + return buff->buffer;
15458 +++ b/extensions/LUA/lua/lzio.h
15461 +** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
15462 +** Buffered streams
15463 +** See Copyright Notice in lua.h
15475 +#define EOZ (-1) /* end of stream */
15477 +typedef struct Zio ZIO;
15479 +#define char2int(c) cast(int, cast(unsigned char, (c)))
15481 +#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
15483 +typedef struct Mbuffer {
15489 +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
15491 +#define luaZ_buffer(buff) ((buff)->buffer)
15492 +#define luaZ_sizebuffer(buff) ((buff)->buffsize)
15493 +#define luaZ_bufflen(buff) ((buff)->n)
15495 +#define luaZ_resetbuffer(buff) ((buff)->n = 0)
15498 +#define luaZ_resizebuffer(L, buff, size) \
15499 + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
15500 + (buff)->buffsize = size)
15502 +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
15505 +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
15506 +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
15508 +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
15509 +LUAI_FUNC int luaZ_lookahead (ZIO *z);
15513 +/* --------- Private Part ------------------ */
15516 + size_t n; /* bytes still unread */
15517 + const char *p; /* current position in buffer */
15518 + lua_Reader reader;
15519 + void* data; /* additional data */
15520 + lua_State *L; /* Lua state (for reader) */
15524 +LUAI_FUNC int luaZ_fill (ZIO *z);
15528 +++ b/extensions/LUA/Makefile
15530 +# Makefile.in generated by automake 1.11.1 from Makefile.am.
15531 +# extensions/LUA/Makefile. Generated from Makefile.in by configure.
15533 +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
15534 +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
15536 +# This Makefile.in is free software; the Free Software Foundation
15537 +# gives unlimited permission to copy and/or distribute it,
15538 +# with or without modifications, as long as this notice is preserved.
15540 +# This program is distributed in the hope that it will be useful,
15541 +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
15542 +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15543 +# PARTICULAR PURPOSE.
15547 +# -*- Makefile -*-
15550 +pkgdatadir = $(datadir)/xtables-addons
15551 +pkgincludedir = $(includedir)/xtables-addons
15552 +pkglibdir = $(libdir)/xtables-addons
15553 +pkglibexecdir = $(libexecdir)/xtables-addons
15554 +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
15555 +install_sh_DATA = $(install_sh) -c -m 644
15556 +install_sh_PROGRAM = $(install_sh) -c
15557 +install_sh_SCRIPT = $(install_sh) -c
15558 +INSTALL_HEADER = $(INSTALL_DATA)
15559 +transform = $(program_transform_name)
15560 +NORMAL_INSTALL = :
15563 +NORMAL_UNINSTALL = :
15565 +POST_UNINSTALL = :
15566 +build_triplet = i686-pc-linux-gnu
15567 +host_triplet = i686-pc-linux-gnu
15568 +DIST_COMMON = $(srcdir)/../../Makefile.extra $(srcdir)/Makefile.am \
15569 + $(srcdir)/Makefile.in
15570 +subdir = extensions/LUA
15571 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
15572 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
15573 + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
15574 + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
15575 + $(top_srcdir)/configure.ac
15576 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
15578 +mkinstalldirs = $(install_sh) -d
15579 +CONFIG_HEADER = $(top_builddir)/config.h
15580 +CONFIG_CLEAN_FILES =
15581 +CONFIG_CLEAN_VPATH_FILES =
15584 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
15585 +ACLOCAL = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run aclocal-1.11
15586 +AMTAR = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run tar
15588 +AUTOCONF = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run autoconf
15589 +AUTOHEADER = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run autoheader
15590 +AUTOMAKE = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run automake-1.11
15593 +CCDEPMODE = depmode=gcc3
15598 +DEFS = -DHAVE_CONFIG_H
15605 +EGREP = /bin/grep -E
15607 +FGREP = /bin/grep -F
15609 +INSTALL = /usr/bin/install -c
15610 +INSTALL_DATA = ${INSTALL} -m 644
15611 +INSTALL_PROGRAM = ${INSTALL}
15612 +INSTALL_SCRIPT = ${INSTALL}
15613 +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
15618 +LIBTOOL = $(SHELL) $(top_builddir)/libtool
15622 +MAKEINFO = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run makeinfo
15623 +MKDIR_P = /bin/mkdir -p
15624 +NM = /usr/bin/nm -B
15630 +PACKAGE = xtables-addons
15631 +PACKAGE_BUGREPORT =
15632 +PACKAGE_NAME = xtables-addons
15633 +PACKAGE_STRING = xtables-addons 1.21
15634 +PACKAGE_TARNAME = xtables-addons
15636 +PACKAGE_VERSION = 1.21
15637 +PATH_SEPARATOR = :
15638 +PKG_CONFIG = /usr/bin/pkg-config
15645 +abs_builddir = /home/andre/Dropbox/xtables-addons/extensions/LUA
15646 +abs_srcdir = /home/andre/Dropbox/xtables-addons/extensions/LUA
15647 +abs_top_builddir = /home/andre/Dropbox/xtables-addons
15648 +abs_top_srcdir = /home/andre/Dropbox/xtables-addons
15651 +am__include = include
15652 +am__leading_dot = .
15654 +am__tar = ${AMTAR} chof - "$$tardir"
15655 +am__untar = ${AMTAR} xf -
15656 +bindir = ${exec_prefix}/bin
15657 +build = i686-pc-linux-gnu
15660 +build_os = linux-gnu
15663 +datadir = ${datarootdir}
15664 +datarootdir = ${prefix}/share
15665 +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
15666 +dvidir = ${docdir}
15667 +exec_prefix = ${prefix}
15668 +host = i686-pc-linux-gnu
15671 +host_os = linux-gnu
15673 +htmldir = ${docdir}
15674 +includedir = ${prefix}/include
15675 +infodir = ${datarootdir}/info
15676 +install_sh = ${SHELL} /home/andre/Dropbox/xtables-addons/install-sh
15677 +kbuilddir = /lib/modules/2.6.33-020633-generic/build
15678 +kinclude_CFLAGS = -I /lib/modules/2.6.33-020633-generic/build/include
15680 +libdir = ${exec_prefix}/lib
15681 +libexecdir = ${exec_prefix}/libexec
15682 +libxtables_CFLAGS =
15683 +libxtables_LIBS = -L/lib -lxtables
15684 +localedir = ${datarootdir}/locale
15685 +localstatedir = ${prefix}/var
15687 +mandir = ${datarootdir}/man
15688 +mkdir_p = /bin/mkdir -p
15689 +oldincludedir = /usr/include
15690 +pdfdir = ${docdir}
15691 +prefix = /usr/local
15692 +program_transform_name = s,x,x,
15694 +regular_CFLAGS = -D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes -Winline -pipe -DXTABLES_LIBDIR=\"${xtlibdir}\"
15695 +sbindir = ${exec_prefix}/sbin
15696 +sharedstatedir = ${prefix}/com
15698 +sysconfdir = ${prefix}/etc
15700 +top_build_prefix = ../../
15701 +top_builddir = ../..
15702 +top_srcdir = ../..
15703 +xtlibdir = ${libexecdir}/xtables
15704 +XA_SRCDIR = ${srcdir}
15705 +XA_TOPSRCDIR = ${top_srcdir}
15706 +XA_ABSTOPSRCDIR = ${abs_top_srcdir}
15707 +_mcall = -f ${top_builddir}/Makefile.iptrules
15711 +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../../Makefile.extra $(am__configure_deps)
15712 + @for dep in $?; do \
15713 + case '$(am__configure_deps)' in \
15715 + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
15716 + && { if test -f $@; then exit 0; else break; fi; }; \
15720 + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/LUA/Makefile'; \
15721 + $(am__cd) $(top_srcdir) && \
15722 + $(AUTOMAKE) --foreign extensions/LUA/Makefile
15723 +.PRECIOUS: Makefile
15724 +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
15726 + *config.status*) \
15727 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
15729 + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
15730 + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
15733 +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
15734 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
15736 +$(top_srcdir)/configure: $(am__configure_deps)
15737 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
15738 +$(ACLOCAL_M4): $(am__aclocal_m4_deps)
15739 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
15740 +$(am__aclocal_m4_deps):
15742 +mostlyclean-libtool:
15746 + -rm -rf .libs _libs
15754 +distdir: $(DISTFILES)
15755 + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
15756 + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
15757 + list='$(DISTFILES)'; \
15758 + dist_files=`for file in $$list; do echo $$file; done | \
15759 + sed -e "s|^$$srcdirstrip/||;t" \
15760 + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
15761 + case $$dist_files in \
15762 + */*) $(MKDIR_P) `echo "$$dist_files" | \
15763 + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
15766 + for file in $$dist_files; do \
15767 + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
15768 + if test -d $$d/$$file; then \
15769 + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
15770 + if test -d "$(distdir)/$$file"; then \
15771 + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
15773 + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
15774 + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
15775 + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
15777 + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
15779 + test -f "$(distdir)/$$file" \
15780 + || cp -p $$d/$$file "$(distdir)/$$file" \
15786 +all-am: Makefile all-local
15788 +install: install-am
15789 +install-exec: install-exec-am
15790 +install-data: install-data-am
15791 +uninstall: uninstall-am
15793 +install-am: all-am
15794 + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
15796 +installcheck: installcheck-am
15798 + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
15799 + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
15800 + `test -z '$(STRIP)' || \
15801 + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
15802 +mostlyclean-generic:
15806 +distclean-generic:
15807 + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
15808 + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
15810 +maintainer-clean-generic:
15811 + @echo "This command is intended for maintainers to use"
15812 + @echo "it deletes files that may require special tools to rebuild."
15815 +clean-am: clean-generic clean-libtool clean-local mostlyclean-am
15817 +distclean: distclean-am
15819 +distclean-am: clean-am distclean-generic
15835 +install-dvi: install-dvi-am
15839 +install-exec-am: install-exec-local
15841 +install-html: install-html-am
15845 +install-info: install-info-am
15851 +install-pdf: install-pdf-am
15855 +install-ps: install-ps-am
15861 +maintainer-clean: maintainer-clean-am
15863 +maintainer-clean-am: distclean-am maintainer-clean-generic
15865 +mostlyclean: mostlyclean-am
15867 +mostlyclean-am: mostlyclean-generic mostlyclean-libtool
15879 +.MAKE: install-am install-strip
15881 +.PHONY: all all-am all-local check check-am clean clean-generic \
15882 + clean-libtool clean-local distclean distclean-generic \
15883 + distclean-libtool distdir dvi dvi-am html html-am info info-am \
15884 + install install-am install-data install-data-am install-dvi \
15885 + install-dvi-am install-exec install-exec-am install-exec-local \
15886 + install-html install-html-am install-info install-info-am \
15887 + install-man install-pdf install-pdf-am install-ps \
15888 + install-ps-am install-strip installcheck installcheck-am \
15889 + installdirs maintainer-clean maintainer-clean-generic \
15890 + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
15891 + ps ps-am uninstall uninstall-am
15894 +export XA_TOPSRCDIR
15895 +export XA_ABSTOPSRCDIR
15897 +all-local: user-all-local
15899 +install-exec-local: user-install-local
15901 +clean-local: user-clean-local
15904 + ${MAKE} ${_mcall} all;
15906 +# Have no user-install-data-local ATM
15907 +user-install-local: user-install-exec-local
15909 +user-install-exec-local:
15910 + ${MAKE} ${_mcall} install;
15913 + ${MAKE} ${_mcall} clean;
15915 +# Tell versions [3.59,3.63) of GNU make to not export all variables.
15916 +# Otherwise a system limit (for SysV at least) may be exceeded.
15920 +++ b/extensions/LUA/Makefile.am
15922 +include ../../Makefile.extra
15924 +++ b/extensions/LUA/Makefile.in
15926 +# Makefile.in generated by automake 1.11.1 from Makefile.am.
15927 +# @configure_input@
15929 +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
15930 +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
15932 +# This Makefile.in is free software; the Free Software Foundation
15933 +# gives unlimited permission to copy and/or distribute it,
15934 +# with or without modifications, as long as this notice is preserved.
15936 +# This program is distributed in the hope that it will be useful,
15937 +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
15938 +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15939 +# PARTICULAR PURPOSE.
15943 +# -*- Makefile -*-
15946 +pkgdatadir = $(datadir)/@PACKAGE@
15947 +pkgincludedir = $(includedir)/@PACKAGE@
15948 +pkglibdir = $(libdir)/@PACKAGE@
15949 +pkglibexecdir = $(libexecdir)/@PACKAGE@
15950 +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
15951 +install_sh_DATA = $(install_sh) -c -m 644
15952 +install_sh_PROGRAM = $(install_sh) -c
15953 +install_sh_SCRIPT = $(install_sh) -c
15954 +INSTALL_HEADER = $(INSTALL_DATA)
15955 +transform = $(program_transform_name)
15956 +NORMAL_INSTALL = :
15959 +NORMAL_UNINSTALL = :
15961 +POST_UNINSTALL = :
15962 +build_triplet = @build@
15963 +host_triplet = @host@
15964 +DIST_COMMON = $(srcdir)/../../Makefile.extra $(srcdir)/Makefile.am \
15965 + $(srcdir)/Makefile.in
15966 +subdir = extensions/LUA
15967 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
15968 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
15969 + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
15970 + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
15971 + $(top_srcdir)/configure.ac
15972 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
15974 +mkinstalldirs = $(install_sh) -d
15975 +CONFIG_HEADER = $(top_builddir)/config.h
15976 +CONFIG_CLEAN_FILES =
15977 +CONFIG_CLEAN_VPATH_FILES =
15980 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
15981 +ACLOCAL = @ACLOCAL@
15984 +AUTOCONF = @AUTOCONF@
15985 +AUTOHEADER = @AUTOHEADER@
15986 +AUTOMAKE = @AUTOMAKE@
15989 +CCDEPMODE = @CCDEPMODE@
15992 +CPPFLAGS = @CPPFLAGS@
15993 +CYGPATH_W = @CYGPATH_W@
15996 +DSYMUTIL = @DSYMUTIL@
15997 +DUMPBIN = @DUMPBIN@
16005 +INSTALL = @INSTALL@
16006 +INSTALL_DATA = @INSTALL_DATA@
16007 +INSTALL_PROGRAM = @INSTALL_PROGRAM@
16008 +INSTALL_SCRIPT = @INSTALL_SCRIPT@
16009 +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
16011 +LDFLAGS = @LDFLAGS@
16012 +LIBOBJS = @LIBOBJS@
16014 +LIBTOOL = @LIBTOOL@
16017 +LTLIBOBJS = @LTLIBOBJS@
16018 +MAKEINFO = @MAKEINFO@
16019 +MKDIR_P = @MKDIR_P@
16022 +OBJDUMP = @OBJDUMP@
16025 +OTOOL64 = @OTOOL64@
16026 +PACKAGE = @PACKAGE@
16027 +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
16028 +PACKAGE_NAME = @PACKAGE_NAME@
16029 +PACKAGE_STRING = @PACKAGE_STRING@
16030 +PACKAGE_TARNAME = @PACKAGE_TARNAME@
16031 +PACKAGE_URL = @PACKAGE_URL@
16032 +PACKAGE_VERSION = @PACKAGE_VERSION@
16033 +PATH_SEPARATOR = @PATH_SEPARATOR@
16034 +PKG_CONFIG = @PKG_CONFIG@
16037 +SET_MAKE = @SET_MAKE@
16040 +VERSION = @VERSION@
16041 +abs_builddir = @abs_builddir@
16042 +abs_srcdir = @abs_srcdir@
16043 +abs_top_builddir = @abs_top_builddir@
16044 +abs_top_srcdir = @abs_top_srcdir@
16045 +ac_ct_CC = @ac_ct_CC@
16046 +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
16047 +am__include = @am__include@
16048 +am__leading_dot = @am__leading_dot@
16049 +am__quote = @am__quote@
16050 +am__tar = @am__tar@
16051 +am__untar = @am__untar@
16054 +build_alias = @build_alias@
16055 +build_cpu = @build_cpu@
16056 +build_os = @build_os@
16057 +build_vendor = @build_vendor@
16058 +builddir = @builddir@
16059 +datadir = @datadir@
16060 +datarootdir = @datarootdir@
16063 +exec_prefix = @exec_prefix@
16065 +host_alias = @host_alias@
16066 +host_cpu = @host_cpu@
16067 +host_os = @host_os@
16068 +host_vendor = @host_vendor@
16069 +htmldir = @htmldir@
16070 +includedir = @includedir@
16071 +infodir = @infodir@
16072 +install_sh = @install_sh@
16073 +kbuilddir = @kbuilddir@
16074 +kinclude_CFLAGS = @kinclude_CFLAGS@
16075 +ksourcedir = @ksourcedir@
16077 +libexecdir = @libexecdir@
16078 +libxtables_CFLAGS = @libxtables_CFLAGS@
16079 +libxtables_LIBS = @libxtables_LIBS@
16080 +localedir = @localedir@
16081 +localstatedir = @localstatedir@
16082 +lt_ECHO = @lt_ECHO@
16084 +mkdir_p = @mkdir_p@
16085 +oldincludedir = @oldincludedir@
16088 +program_transform_name = @program_transform_name@
16090 +regular_CFLAGS = @regular_CFLAGS@
16091 +sbindir = @sbindir@
16092 +sharedstatedir = @sharedstatedir@
16094 +sysconfdir = @sysconfdir@
16095 +target_alias = @target_alias@
16096 +top_build_prefix = @top_build_prefix@
16097 +top_builddir = @top_builddir@
16098 +top_srcdir = @top_srcdir@
16099 +xtlibdir = @xtlibdir@
16100 +XA_SRCDIR = ${srcdir}
16101 +XA_TOPSRCDIR = ${top_srcdir}
16102 +XA_ABSTOPSRCDIR = ${abs_top_srcdir}
16103 +_mcall = -f ${top_builddir}/Makefile.iptrules
16107 +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../../Makefile.extra $(am__configure_deps)
16108 + @for dep in $?; do \
16109 + case '$(am__configure_deps)' in \
16111 + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
16112 + && { if test -f $@; then exit 0; else break; fi; }; \
16116 + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/LUA/Makefile'; \
16117 + $(am__cd) $(top_srcdir) && \
16118 + $(AUTOMAKE) --foreign extensions/LUA/Makefile
16119 +.PRECIOUS: Makefile
16120 +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
16122 + *config.status*) \
16123 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
16125 + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
16126 + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
16129 +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
16130 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
16132 +$(top_srcdir)/configure: $(am__configure_deps)
16133 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
16134 +$(ACLOCAL_M4): $(am__aclocal_m4_deps)
16135 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
16136 +$(am__aclocal_m4_deps):
16138 +mostlyclean-libtool:
16142 + -rm -rf .libs _libs
16150 +distdir: $(DISTFILES)
16151 + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
16152 + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
16153 + list='$(DISTFILES)'; \
16154 + dist_files=`for file in $$list; do echo $$file; done | \
16155 + sed -e "s|^$$srcdirstrip/||;t" \
16156 + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
16157 + case $$dist_files in \
16158 + */*) $(MKDIR_P) `echo "$$dist_files" | \
16159 + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
16162 + for file in $$dist_files; do \
16163 + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
16164 + if test -d $$d/$$file; then \
16165 + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
16166 + if test -d "$(distdir)/$$file"; then \
16167 + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
16169 + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
16170 + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
16171 + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
16173 + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
16175 + test -f "$(distdir)/$$file" \
16176 + || cp -p $$d/$$file "$(distdir)/$$file" \
16182 +all-am: Makefile all-local
16184 +install: install-am
16185 +install-exec: install-exec-am
16186 +install-data: install-data-am
16187 +uninstall: uninstall-am
16189 +install-am: all-am
16190 + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
16192 +installcheck: installcheck-am
16194 + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
16195 + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
16196 + `test -z '$(STRIP)' || \
16197 + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
16198 +mostlyclean-generic:
16202 +distclean-generic:
16203 + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
16204 + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
16206 +maintainer-clean-generic:
16207 + @echo "This command is intended for maintainers to use"
16208 + @echo "it deletes files that may require special tools to rebuild."
16211 +clean-am: clean-generic clean-libtool clean-local mostlyclean-am
16213 +distclean: distclean-am
16215 +distclean-am: clean-am distclean-generic
16231 +install-dvi: install-dvi-am
16235 +install-exec-am: install-exec-local
16237 +install-html: install-html-am
16241 +install-info: install-info-am
16247 +install-pdf: install-pdf-am
16251 +install-ps: install-ps-am
16257 +maintainer-clean: maintainer-clean-am
16259 +maintainer-clean-am: distclean-am maintainer-clean-generic
16261 +mostlyclean: mostlyclean-am
16263 +mostlyclean-am: mostlyclean-generic mostlyclean-libtool
16275 +.MAKE: install-am install-strip
16277 +.PHONY: all all-am all-local check check-am clean clean-generic \
16278 + clean-libtool clean-local distclean distclean-generic \
16279 + distclean-libtool distdir dvi dvi-am html html-am info info-am \
16280 + install install-am install-data install-data-am install-dvi \
16281 + install-dvi-am install-exec install-exec-am install-exec-local \
16282 + install-html install-html-am install-info install-info-am \
16283 + install-man install-pdf install-pdf-am install-ps \
16284 + install-ps-am install-strip installcheck installcheck-am \
16285 + installdirs maintainer-clean maintainer-clean-generic \
16286 + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
16287 + ps ps-am uninstall uninstall-am
16290 +export XA_TOPSRCDIR
16291 +export XA_ABSTOPSRCDIR
16293 +all-local: user-all-local
16295 +install-exec-local: user-install-local
16297 +clean-local: user-clean-local
16300 + ${MAKE} ${_mcall} all;
16302 +# Have no user-install-data-local ATM
16303 +user-install-local: user-install-exec-local
16305 +user-install-exec-local:
16306 + ${MAKE} ${_mcall} install;
16309 + ${MAKE} ${_mcall} clean;
16311 +# Tell versions [3.59,3.63) of GNU make to not export all variables.
16312 +# Otherwise a system limit (for SysV at least) may be exceeded.
16316 +++ b/extensions/LUA/Mbuild
16318 +# -*- Makefile -*-
16320 +obj-${build_LUA} += libxt_LUA.so
16322 +++ b/extensions/LUA/nf_lua.c
16324 +#if defined(__KERNEL__)
16326 +#include <linux/kernel.h>
16327 +#include <linux/slab.h>
16328 +#include <linux/string.h>
16329 +#include <linux/timer.h>
16330 +#include <linux/random.h>
16331 +#include <linux/netfilter/x_tables.h>
16336 +#include "lobject.h" /*sizeof(udata) */
16337 +#include "lauxlib.h"
16338 +#include "controller.h"
16340 +#if defined(__KERNEL__) /* reachs until luaopen_nflib */
16343 +static int32_t nf_get_random(lua_State *L)
16345 + uint32_t rand = 0;
16347 + get_random_bytes(&rand, sizeof(uint32_t ));
16348 + lua_pushnumber(L, rand);
16352 +static int32_t nf_get_time(lua_State *L)
16354 + lua_pushnumber(L, jiffies_to_msecs(jiffies_64));
16358 +static const struct luaL_Reg nf_lua_lib_f [] = {
16359 + { "get_random", nf_get_random },
16360 + { "get_time", nf_get_time },
16364 +void luaopen_nflib(lua_State *L)
16368 + luaL_register(L, NETFILTER_LIB, nf_lua_lib_f);
16371 + /* registering verdicts inside the _G */
16372 + lua_getglobal(L, "_G");
16373 + top = lua_gettop(L);
16375 + lua_pushinteger(L, XT_CONTINUE);
16376 + lua_setfield(L, top, "XT_CONTINUE"); /* continiue with next rule */
16378 + lua_pushinteger(L, NF_DROP);
16379 + lua_setfield(L, top, "NF_DROP"); /* stop traversal in the current table hook and drop packet */
16381 + lua_pushinteger(L, NF_ACCEPT);
16382 + lua_setfield(L, top, "NF_ACCEPT"); /* stop traversal in the current table hook and accept packet */
16384 + lua_pop(L, 1); /* pop _G */
16389 +++ b/extensions/LUA/prot_buf_dynamic.c
16392 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
16393 + * by Andre Graf <andre@dergraf.org>
16395 + * This program is free software; you can redistribute it and/or modify
16396 + * it under the terms of the GNU General Public License as published by
16397 + * the Free Software Foundation; either version 2 of the License, or
16398 + * (at your option) any later version.
16400 + * This program is distributed in the hope that it will be useful,
16401 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16402 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16403 + * GNU General Public License for more details.
16405 + * You should have received a copy of the GNU General Public License
16406 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
16409 +#include "controller.h"
16413 +struct protocol_buf * dyn_prot_buf_array[MAX_NR_OF_DYN_PROT_BUFS] = { NULL };
16416 +/* LUA_API: the function 'field_dynamic_setter' acts as a wrapper around
16417 + * a given Lua field setter function of a dynamic protocol buffer. The
16418 + * string containing the lua function name was piggybacked in the 'set'
16419 + * member of the protocol_field. We call this function passing the actual
16420 + * segment as byte array and the set value.
16423 + * 1. lua_packet_segment (implicit)
16424 + * 2. some lua value
16427 + * 1. pointer to the protocol buffer
16431 + * 1. true or false if the 'set' was successful
16433 +int32_t field_dynamic_setter(lua_State *L)
16436 + lua_packet_segment * array;
16437 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
16438 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
16440 + int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
16442 + /* the function name is piggybacked as a string */
16443 + lua_getglobal(L, (char *)prot_buf->protocol_fields[field_index].set);
16444 + if (!lua_isfunction(L, -1)) {
16445 + lua_pushboolean(L, 0);
16449 + nbytes = sizeof(lua_packet_segment) + seg->length * sizeof(uint8_t);
16450 + array = (lua_packet_segment *)lua_newuserdata(L, nbytes);
16451 + array->length = seg->length;
16452 + array->start = seg->start + seg->offset;
16453 + array->changes = NULL;
16455 + luaL_getmetatable(L, LUA_BYTE_ARRAY);
16456 + lua_setmetatable(L, -2);
16457 + lua_pushvalue(L, 2); /* push value to set */
16458 + if (lua_pcall(L, 2, 1, 0) != 0) {
16459 + pr_debug("Error: %s \n", lua_tostring(L, -1));
16461 + lua_pushboolean(L, 0);
16466 +/* LUA_API: the function 'field_dynamic_getter' acts as a wrapper around
16467 + * a given Lua field getter function of a dynamic protocol buffer. The
16468 + * string containing the lua function name was piggybacked in the 'get'
16469 + * member of the protocol_field. We call this function passing the actual
16470 + * segment as byte array.
16473 + * 1. lua_packet_segment (implicit)
16476 + * 1. pointer to the protocol buffer
16480 + * 1. true or false if the 'get' was successful
16482 +int32_t field_dynamic_getter(lua_State *L)
16485 + lua_packet_segment * array;
16486 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
16487 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
16489 + int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
16491 + /* the function name is piggybacked as a string */
16492 + lua_getglobal(L, (char *)prot_buf->protocol_fields[field_index].get);
16493 + if (!lua_isfunction(L, -1)) {
16494 + lua_pushboolean(L, 0);
16498 + nbytes = sizeof(lua_packet_segment) + seg->length * sizeof(uint8_t);
16499 + array = (lua_packet_segment *)lua_newuserdata(L, nbytes);
16500 + array->length = seg->length;
16501 + array->start = seg->start + seg->offset;
16502 + array->changes = NULL;
16504 + luaL_getmetatable(L, LUA_BYTE_ARRAY);
16505 + lua_setmetatable(L, -2);
16506 + if (lua_pcall(L, 1, 1, 0) != 0) {
16507 + pr_debug("Error: %s \n", luaL_checkstring(L, -1));
16509 + lua_pushboolean(L, 0);
16514 +/* LUA_API: the function 'has_protocol_dynamic' acts as a wrapper around
16515 + * a given lua has_protocol function of a dynamic protocol buffer. The
16516 + * string containing the lua function name was piggybacked in the 'has_protocol'
16517 + * member of the protocol_buffer. We call this function passing the actual
16521 + * 1. lua_packet_segment
16522 + * 2. protocol type
16525 + * 1. true or false if the payload field contains the given protocol
16527 +int32_t has_protocol_dynamic(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t type)
16529 + lua_packet_segment *seg_new;
16532 + /* the function name is piggybacked as a string */
16533 + lua_getglobal(L, (char *)prot_buf->has_protocol);
16534 + seg_new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
16535 + seg_new->start = seg->start;
16536 + seg_new->offset = seg->offset;
16537 + seg_new->length = seg->length;
16538 + seg_new->changes = NULL;
16539 + luaL_getmetatable(L, prot_buf->name);
16540 + lua_setmetatable(L, -2);
16541 + lua_pushinteger(L, type); /* push the protocol type */
16542 + if (lua_pcall(L, 2, 1, 0) != 0) {
16543 + pr_debug("Error: %s \n", luaL_checkstring(L, -1));
16547 + res = lua_toboolean(L, -1);
16553 +/* LUA_API: the function 'get_field_changes_dynamic' acts as a wrapper around
16554 + * a given lua get_field_changes function of a dynamic protocol buffer. The
16555 + * string containing the lua function name was piggybacked in the 'get_field_changes'
16556 + * member of the protocol_buffer. We call this function passing the actual
16557 + * segment. The lua function must return two lua table containing the offset
16558 + * and length changes (in bits).
16561 + * 1. lua_packet_segment
16564 + * 1. new allocated field_changes struct
16566 +struct field_changes * get_field_changes_dynamic(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg)
16568 + lua_packet_segment *seg_new;
16569 + struct field_changes * changes;
16570 + int32_t nr_of_changes, i;
16572 + lua_getglobal(L, (char *)prot_buf->get_field_changes);
16574 + seg_new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
16575 + seg_new->start = seg->start;
16576 + seg_new->offset = seg->offset;
16577 + seg_new->length = seg->length;
16578 + seg_new->changes = NULL;
16579 + luaL_getmetatable(L, prot_buf->name);
16580 + lua_setmetatable(L, -2);
16582 + if (lua_pcall(L, 1, 2, 0) != 0)
16583 + luaL_error(L, "inside get_field_changes_dynamic. %s\n", lua_tostring(L, -1));
16585 + /* the function call must return a table containing length changes */
16586 + luaL_checktype(L, -1, LUA_TTABLE);
16587 + /* the function call must return a table containing offset changes */
16588 + luaL_checktype(L, -2, LUA_TTABLE);
16589 + /* both tables have to be of same size */
16590 + if (lua_objlen(L, -1) != lua_objlen(L, -2))
16591 + luaL_error(L, "the provided tables are not of equal size");
16593 + nr_of_changes = lua_objlen(L, -1);
16594 + changes = get_allocated_field_changes(L, nr_of_changes);
16596 + /* loop over the tables */
16597 + for (i = 1; i < nr_of_changes; i++) {
16598 + lua_rawgeti(L, -1, i); /* push length value of field at index i */
16599 + changes->field_length_changes[i - 1] = luaL_checkinteger(L, -1);
16600 + lua_pop(L, 1); /* pop offset value */
16602 + lua_rawgeti(L, -2, i); /* push offset value of field at index i */
16603 + changes->field_offset_changes[i - 1] = luaL_checkinteger(L, -1);
16604 + lua_pop(L, 1); /* pop length value */
16607 + /* pop both tables */
16613 +/* C_INT: 'get_free_protocol_index' is only used internally. This function
16614 + * gets a free slot inside the array holding all the protocol buffers.
16615 + * There are several ways to get to this information. In this case I take
16616 + * the way over the reflected array SUPPORTED_PROTOCOL_TABLE inside the
16617 + * Lua state. Since this function is called at laodtime, we do not have
16618 + * to care about performance.
16620 +static int32_t get_free_protocol_index(lua_State *L)
16622 + int32_t protocol_index;
16624 + lua_getglobal(L, SUPPORTED_PROTOCOL_TABLE);
16625 + protocol_index = lua_objlen(L, -1) + 1;
16627 + return protocol_index;
16630 +/* C_API: 'free_dynamic_prot_buf' frees the allocated memory of a given
16631 + * dynamic protocol buffer. this function is normally called inside a
16632 + * cleanup routine. Be aware, before running this function you must be
16633 + * sure that no references to the dynamic protocol buffers were available.
16634 + * It's recomended to close the Lua state before calling the function. */
16635 +void free_dynamic_prot_buf(struct protocol_buf * prot_buf)
16637 + struct protocol_field * field = prot_buf->protocol_fields;
16639 + for (; field->name != NULL; field++) {
16640 + if (field->get) kfree(field->get);
16641 + if (field->set) kfree(field->set);
16642 + if (field->name) kfree((char *)field->name);
16645 + if (prot_buf->payload_field) kfree(prot_buf->payload_field);
16646 + if (prot_buf->has_protocol) kfree(prot_buf->has_protocol);
16648 + if (prot_buf->get_field_changes) kfree(prot_buf->get_field_changes);
16649 + kfree((char *)prot_buf->name);
16654 +void cleanup_dynamic_prot_bufs(void)
16658 + for (i = 0; i < MAX_NR_OF_DYN_PROT_BUFS; i++) {
16659 + if (dyn_prot_buf_array[i]) {
16660 + free_dynamic_prot_buf(dyn_prot_buf_array[i]);
16661 + dyn_prot_buf_array[i] = NULL;
16668 +/* C_INT: 'free_protocol_fields' is used internally as a helper function for
16669 + * 'register_dynamic_protbuf'. It is used when durin registration an error
16670 + * occurs and the afore allocated fields needed to be freed. */
16671 +static inline void free_protocol_fields(struct protocol_field * prot_fields, int32_t i)
16673 + struct protocol_field * f;
16676 + f = &prot_fields[i];
16677 + if (f->name) kfree((void *)f->name);
16678 + if (f->get) kfree((void *)f->get);
16679 + if (f->set) kfree((void *)f->set);
16680 + kfree((void *)f);
16685 +/* LUA_API: 'register_dynamic_protbuf' is called from within the Lua script.
16686 + * it takes a Lua table representing the dynamic protocol buffer as parameter.
16688 + * eth_prot_buf = {
16689 + * name = "packet_eth_dyn",
16690 + * payload_field = "data",
16691 + * protocol_fields = {
16692 + * {"dmac", 0, 48, nil, nil },
16693 + * {"smac", 48, 48, nil, nil },
16694 + * {"type", 96, 16, nil, nil },
16695 + * {"data", 112, 0, nil, nil },
16697 + * has_protocol = "eth_dyn_has_protocol",
16698 + * get_field_changes = "eth_dyn_get_field_changes"
16700 + * register_dynamic_protbuf(eth_prot_buf)
16702 + * the table gets parsed and a new protocol_buf struct is allocated and
16703 + * initialized using 'register_protbuf', which is also used for the static
16704 + * protocol buffers. This enables an identical behavior like the static
16705 + * protocol buffers. The dynamic protocol buffers are not garbage collected,
16706 + * use 'free_dynamic_protbuf' to free them after closing the Lua state.
16708 +static int32_t register_dynamic_protbuf(lua_State *L)
16710 + struct protocol_buf *prot_buf;
16711 + struct protocol_field *field, sentinel = PROT_FIELD_SENTINEL;
16712 + int32_t nr_of_fields, i;
16714 + prot_buf = (struct protocol_buf *)kmalloc(sizeof(struct protocol_buf), GFP_KERNEL);
16715 + prot_buf->is_dynamic = 1;
16717 + /* check if parameter is a table */
16718 + luaL_checktype(L, 1, LUA_TTABLE);
16720 + /* initialize prot_buf.name */
16721 + lua_getfield(L, 1, "name");
16722 + prot_buf->name = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
16723 + strcpy((char *)prot_buf->name, luaL_checkstring(L, -1));
16724 + lua_pop(L, 1); /* pop res from lua_getfield */
16726 + /* check if protocol buffer is already registered */
16727 + lua_getglobal(L, prot_buf->name);
16728 + if (!lua_isnil(L, -1)) {
16729 + lua_pop(L, 1); /* pop res from lua_getglobal */
16730 + pr_debug("protocol_buf '%s' already registered.\n", prot_buf->name);
16731 + goto free_prot_buf;
16733 + lua_pop(L, 1); /* pop res from lua_getglobal */
16735 + /* initialize payload field */
16736 + lua_getfield(L, 1, "payload_field");
16737 + if (lua_isstring(L, -1)) {
16738 + prot_buf->payload_field = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
16739 + strcpy(prot_buf->payload_field, lua_tostring(L, -1));
16741 + prot_buf->payload_field = NULL;
16742 + lua_pop(L, 1); /* pop res from lua_getfield */
16744 + /* initialize protocol_fields field*/
16745 + lua_getfield(L, 1, "protocol_fields");
16746 + if (!lua_istable(L, -1)) {
16747 + pr_debug("invalid protocol_fields table.\n");
16752 + nr_of_fields = lua_objlen(L, -1);
16753 + prot_buf->protocol_fields = (struct protocol_field *)kmalloc((nr_of_fields + 1) * sizeof(struct protocol_field), GFP_KERNEL);
16755 + for (i = 1; i <= nr_of_fields; i++) {
16756 + field = &prot_buf->protocol_fields[i - 1];
16757 + /* initialize protocol field */
16758 + lua_rawgeti(L, -1, i); /* push field-table */
16759 + if (!lua_istable(L, -1)) {
16760 + free_protocol_fields(prot_buf->protocol_fields, i);
16761 + pr_debug("invalid protocol_field at %i.\n", i);
16765 + /* initialize protocol field name */
16766 + lua_rawgeti(L, -1, 1);
16767 + if (!lua_isstring(L, -1)) {
16768 + free_protocol_fields(prot_buf->protocol_fields, i);
16769 + pr_debug("invalid protocol_field name at %i.\n", i);
16773 + field->name = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
16774 + strcpy((char*)field->name, lua_tostring(L, -1));
16775 + lua_pop(L, 1); /* pop field name */
16777 + /* initialize protocol field offset */
16778 + lua_rawgeti(L, -1, 2);
16779 + if (!lua_isnumber(L, -1)) {
16780 + free_protocol_fields(prot_buf->protocol_fields, i);
16781 + pr_debug("invalid protocol_field offset at %i.\n", i);
16784 + field->offset = lua_tointeger(L, -1);
16785 + lua_pop(L, 1); /* pop field offset */
16787 + /* initialize protocol field length */
16788 + lua_rawgeti(L, -1, 3);
16789 + if (!lua_isnumber(L, -1)) {
16790 + free_protocol_fields(prot_buf->protocol_fields, i);
16791 + pr_debug("invalid protocol_field length at %i.\n", i);
16794 + field->length = lua_tointeger(L, -1);
16795 + lua_pop(L, 1); /* pop field length */
16797 + /* initialize protocol field getter */
16798 + lua_rawgeti(L, -1, 4);
16799 + if (lua_isstring(L, -1)) {
16800 + field->get = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
16801 + strcpy((char *)field->get, lua_tostring(L, -1)); /* the get-wrapper knows about the piggybacked string */
16803 + field->get = NULL;
16804 + lua_pop(L, 1); /* pop field getter */
16806 + /* initialize protocol field setter */
16807 + lua_rawgeti(L, -1, 5);
16808 + if (lua_isstring(L, -1)) {
16809 + field->set = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
16810 + strcpy((char *)field->set, lua_tostring(L, -1)); /* the set-wrapper knows about the piggybacked string */
16812 + field->set = NULL;
16813 + lua_pop(L, 1); /* pop field setter */
16815 + /* field initialization completed */
16816 + lua_pop(L, 1); /* pop field-table */
16819 + /* put sentinel at the end of protocol_fields */
16820 + memcpy(&prot_buf->protocol_fields[nr_of_fields], &sentinel, sizeof(sentinel));
16821 + lua_pop(L, 1); /* pop protocol-fields-table */
16823 + /* initialize has_protocol field */
16824 + lua_getfield(L, 1, "has_protocol");
16825 + if (lua_isstring(L, -1)) {
16826 + prot_buf->has_protocol = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
16827 + strcpy((char *)prot_buf->has_protocol, lua_tostring(L, -1)); /* the has_protocol-wrapper knows about the piggybacked string */
16829 + prot_buf->has_protocol = NULL;
16830 + lua_pop(L, 1); /* pop has_protocol */
16832 + /* initialize get_field_changes field */
16833 + lua_getfield(L, 1, "get_field_changes");
16834 + if (lua_isstring(L, -1)) {
16835 + prot_buf->get_field_changes = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
16836 + strcpy((char *)prot_buf->get_field_changes, lua_tostring(L, -1)); /* the get_field_changes-wrapper knows about the piggybacked string */
16838 + prot_buf->get_field_changes = NULL;
16839 + lua_pop(L, 1); /* pop get_field_changes */
16841 + /* Storing the pointer to the DYNAMIC protbuf within dyn_prot_buf_array, in order to free it at cleanup */
16842 + for (i = 0; i < MAX_NR_OF_DYN_PROT_BUFS; i++) {
16843 + if (!dyn_prot_buf_array[i]) {
16844 + dyn_prot_buf_array[i] = prot_buf;
16850 + /* call the "common" register_protbuf */
16851 + register_protbuf(L, prot_buf, get_free_protocol_index(L)); /* register prot_buf as it is done with the static ones */
16856 + kfree(prot_buf->protocol_fields);
16858 + if (prot_buf->payload_field) kfree(prot_buf->payload_field);
16860 + kfree((void *)prot_buf->name);
16863 + luaL_error(L, "one or more error happend while registering a dynamic protocol buffer, please consult the debug log");
16869 +void luaopen_protbuf_dynamic(lua_State *L)
16871 + lua_getglobal(L, "_G");
16872 + lua_pushcclosure(L, register_dynamic_protbuf, 0);
16873 + lua_setfield(L, -2, "register_dynamic_protbuf");
16874 + lua_pop(L, 1); /* pop _G */
16878 +++ b/extensions/LUA/prot_buf_ethernet.c
16881 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
16882 + * by Andre Graf <andre@dergraf.org>
16884 + * This program is free software; you can redistribute it and/or modify
16885 + * it under the terms of the GNU General Public License as published by
16886 + * the Free Software Foundation; either version 2 of the License, or
16887 + * (at your option) any later version.
16889 + * This program is distributed in the hope that it will be useful,
16890 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16891 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16892 + * GNU General Public License for more details.
16894 + * You should have received a copy of the GNU General Public License
16895 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
16898 +#include "controller.h"
16901 +static int32_t eth_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
16903 + uint8_t *embedded_protocol = seg->start + seg->offset + 12 /*bytes*/;
16904 + unsigned short res = (unsigned short)((embedded_protocol[1] << CHAR_BIT) | (embedded_protocol[0] << CHAR_BIT));
16907 + case 0x0800: /* 1: Internet Protocol (IP) */
16908 + if (protocol_type == PACKET_IP) return 1;
16917 +static const struct protocol_field eth_protocol_fields[] = {
16918 + /* field name offset length getter setter */
16919 + { "dmac", 0, 48, NULL, NULL },
16920 + { "smac", 48, 48, NULL, NULL },
16921 + { "type", 96, 16, NULL, NULL },
16922 + { "data", 112, 0, NULL, NULL },
16923 + PROT_FIELD_SENTINEL,
16926 +static const struct protocol_buf eth_protocol_buf = {
16928 + .name = LUA_PACKET_SEG_ETH,
16929 + .payload_field = "data",
16930 + .protocol_fields = (struct protocol_field *)ð_protocol_fields,
16931 + .has_protocol = ð_has_protocol,
16932 + .get_field_changes = NULL,
16936 +void luaopen_protbuf_eth(lua_State *L)
16938 + register_protbuf(L, (struct protocol_buf *)ð_protocol_buf, PACKET_ETH);
16941 +++ b/extensions/LUA/prot_buf_helpers.c
16944 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
16945 + * by Andre Graf <andre@dergraf.org>
16947 + * This program is free software; you can redistribute it and/or modify
16948 + * it under the terms of the GNU General Public License as published by
16949 + * the Free Software Foundation; either version 2 of the License, or
16950 + * (at your option) any later version.
16952 + * This program is distributed in the hope that it will be useful,
16953 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16954 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16955 + * GNU General Public License for more details.
16957 + * You should have received a copy of the GNU General Public License
16958 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
16961 +#if defined(__KERNEL__)
16962 +#include <linux/netfilter_ipv4.h>
16963 +#include <linux/slab.h> /* kmalloc */
16966 +#include "controller.h"
16968 +int32_t get_header_size(struct protocol_buf * prot_buf)
16970 + int32_t bit_counter = 0;
16971 + struct protocol_field * field = prot_buf->protocol_fields;
16973 + for (; field->name; field++)
16974 + bit_counter += field->length;
16976 + return bit_counter >> 3;
16980 +int32_t set_32_bit_generic(lua_State *L)
16982 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
16983 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
16985 + *(uint32_t *)(seg->start + seg->offset) = (uint32_t )htonl(luaL_checkinteger(L, 2));
16988 +int32_t get_32_bit_generic(lua_State *L)
16990 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
16991 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
16993 + lua_pushinteger(L, ntohl(*((uint32_t *)(seg->start + seg->offset))));
16997 +int32_t set_16_bit_generic(lua_State *L)
16999 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17000 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17002 + *(uint16_t *)(seg->start + seg->offset) = (uint16_t)htons(luaL_checkinteger(L, 2));
17005 +int32_t get_16_bit_generic(lua_State *L)
17007 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17008 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17010 + lua_pushinteger(L, ntohs(*((uint16_t *)(seg->start + seg->offset))));
17014 +int32_t set_lower_4_bit_generic(lua_State *L)
17016 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17017 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17018 + uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
17019 + uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
17021 + *pos &= 0x0F; /* reset lower 4 bits*/
17027 +int32_t get_lower_4_bit_generic(lua_State *L)
17029 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17030 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17032 + lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) >> 4);
17036 +int32_t set_upper_4_bit_generic(lua_State *L)
17038 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17039 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17040 + uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
17041 + uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
17043 + *pos &= 0xF0; /* reset upper 4 bits*/
17044 + *pos |= (b >> 4);
17049 +int32_t get_upper_4_bit_generic(lua_State *L)
17051 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17052 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17054 + lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) & 0x0F);
17059 +int32_t set_8_bit_generic(lua_State *L)
17061 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17062 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17064 + *(uint8_t *)(seg->start + seg->offset) = (uint8_t)luaL_checkinteger(L, 2);
17068 +int32_t get_8_bit_generic(lua_State *L)
17070 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17071 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17073 + lua_pushinteger(L, *(uint8_t *)(seg->start + seg->offset));
17077 +int32_t set_1_bit_generic(lua_State *L)
17079 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17080 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17081 + unsigned long l = 0;
17083 + memcpy(&l, (seg->start + seg->offset), seg->length);
17084 + l |= (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
17085 + memcpy((seg->start + seg->offset), &l, seg->length);
17090 +int32_t get_1_bit_generic(lua_State *L)
17092 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17093 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17094 + unsigned long l = 0;
17095 + uint32_t bit = 0;
17097 + memcpy(&l, (seg->start + seg->offset), seg->length);
17098 + bit = l & (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
17100 + lua_pushboolean(L, bit);
17104 +int32_t get_string_generic(lua_State *L)
17106 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17107 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17109 + /* Warning we cast from uchar to char */
17110 + lua_pushlstring(L, (char *)seg->start + seg->offset, seg->length);
17114 +int32_t set_data_generic(lua_State *L)
17116 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17117 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17118 + lua_packet_segment * data = checkbytearray(L, 2);
17120 + pr_debug("seg->length %u, data->length %u\n", seg->length, data->length);
17122 + if (seg->length >= data->length)
17123 + memcpy((seg->start + seg->offset), data->start, data->length);
17125 + luaL_error(L, "provided byte array too big for given packet segment");
17129 +struct field_changes * get_allocated_field_changes(lua_State *L, int32_t nr_of_fields)
17131 + struct field_changes * changes;
17133 + changes = kmalloc(sizeof(struct field_changes), GFP_ATOMIC);
17138 + changes->field_length_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
17139 + if (!changes->field_length_changes)
17142 + changes->field_offset_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
17143 + if (!changes->field_offset_changes)
17146 + memset(changes->field_length_changes, 0, nr_of_fields * sizeof(int));
17147 + memset(changes->field_offset_changes, 0, nr_of_fields * sizeof(int));
17149 + changes->ref_count = 1;
17153 +free2: kfree(changes->field_length_changes);
17154 +free1: kfree(changes);
17156 + if (!changes) luaL_error(L, "couldnt allocate memory inside 'get_allocated_field_changes'");
17157 + return NULL; /* only to omit warnings */
17159 \ No newline at end of file
17161 +++ b/extensions/LUA/prot_buf_icmp.c
17164 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17165 + * by Andre Graf <andre@dergraf.org>
17167 + * This program is free software; you can redistribute it and/or modify
17168 + * it under the terms of the GNU General Public License as published by
17169 + * the Free Software Foundation; either version 2 of the License, or
17170 + * (at your option) any later version.
17172 + * This program is distributed in the hope that it will be useful,
17173 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17174 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17175 + * GNU General Public License for more details.
17177 + * You should have received a copy of the GNU General Public License
17178 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17181 +#include "controller.h"
17183 +static int32_t icmp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
17188 +static const struct protocol_field icmp_protocol_fields[] = {
17189 + /* field name offset length getter setter */
17190 + { "type", 0, 8, NULL, NULL },
17191 + { "code", 8, 8, NULL, NULL },
17192 + { "checksum", 16, 16, NULL, NULL },
17193 + { "id", 32, 16, NULL, NULL },
17194 + { "sequence", 48, 16, NULL, NULL },
17195 + PROT_FIELD_SENTINEL,
17198 +static const struct protocol_buf icmp_protocol_buf = {
17200 + .name = LUA_PACKET_SEG_ICMP,
17201 + .payload_field = NULL,
17202 + .protocol_fields = (struct protocol_field *)&icmp_protocol_fields,
17203 + .has_protocol = &icmp_has_protocol,
17204 + .get_field_changes = NULL,
17207 +void luaopen_protbuf_icmp(lua_State *L)
17209 + register_protbuf(L, (struct protocol_buf *)&icmp_protocol_buf, PACKET_ICMP);
17213 +++ b/extensions/LUA/prot_buf_ip.c
17216 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17217 + * by Andre Graf <andre@dergraf.org>
17219 + * This program is free software; you can redistribute it and/or modify
17220 + * it under the terms of the GNU General Public License as published by
17221 + * the Free Software Foundation; either version 2 of the License, or
17222 + * (at your option) any later version.
17224 + * This program is distributed in the hope that it will be useful,
17225 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17226 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17227 + * GNU General Public License for more details.
17229 + * You should have received a copy of the GNU General Public License
17230 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17233 +#if defined(__KERNEL__)
17234 + #include <net/checksum.h>
17235 + #include <net/tcp.h>
17238 +#include "controller.h"
17241 +#define IP_FMT "%u.%u.%u.%u"
17242 +#define IP_ACC(buf) buf[0], buf[1], buf[2], buf[3]
17245 +static int32_t ip_version_set(lua_State *L)
17247 + uint8_t version_checked;
17248 + lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
17249 + uint8_t *version_seg = seg->start + seg->offset;
17250 + int32_t version = luaL_checkinteger(L, 2);
17252 + luaL_argcheck(L, version >= 0 && version <= 15, 1, "version number invalid");
17254 + version_checked = (uint8_t)version;
17256 + version_seg[0] &= (uint8_t)0x0F; /* reset version bits */
17257 + version_seg[0] |= version_checked << 4;
17261 +static int32_t ip_version_get(lua_State *L)
17263 + lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
17264 + uint8_t *version_seg = seg->start + seg->offset;
17265 + uint8_t v = version_seg[0] & 0xF0;
17269 + lua_pushinteger(L, v);
17273 +static int32_t ip_ihl_set(lua_State *L)
17275 + uint8_t ihl_checked;
17276 + lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
17277 + uint8_t *ihl_seg = seg->start + seg->offset;
17278 + int32_t ihl = luaL_checkinteger(L, 2);
17280 + luaL_argcheck(L, ihl >= 5 && ihl <= 15, 1, "ip header length invalid"); // RFC 791 5x32 = 160 bits
17282 + ihl_checked = (uint8_t)ihl;
17284 + ihl_seg[0] &= (uint8_t)0xF0; /* reset ihl bits */
17285 + ihl_seg[0] |= ihl_checked;
17289 +static int32_t ip_ihl_get(lua_State *L)
17291 + lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
17292 + uint8_t *ihl_seg = seg->start + seg->offset;
17293 + uint8_t v = ihl_seg[0] & 0x0F;
17295 + lua_pushinteger(L, v);
17299 +static int32_t ip_addr_set(lua_State *L)
17301 + int32_t field_id = lua_tointeger(L, lua_upvalueindex(2));
17302 + lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
17303 + uint8_t *addr_seg = seg->start + seg->offset;
17304 + uint32_t old_addr;
17305 + char *ip = (char *)luaL_checkstring(L, 2);
17306 + uint32_t a, b, c, d;
17307 + struct sk_buff * skb = (struct sk_buff *)lua_touserdata(L, 3);
17309 + /* for tcp / udp checksumming*/
17310 + uint32_t prot_offset;
17311 + uint8_t *check, *protocol_seg;
17315 + sscanf(ip, IP_FMT, &a, &b, &c, &d);
17317 + luaL_argcheck(L, a < 256 && b < 256 && c < 256 && d < 256, 1, "invalid ip addr");
17319 + old_addr = *((uint32_t *)addr_seg);
17320 + addr_seg[0] = (uint8_t)a;
17321 + addr_seg[1] = (uint8_t)b;
17322 + addr_seg[2] = (uint8_t)c;
17323 + addr_seg[3] = (uint8_t)d;
17325 +#if defined(__KERNEL__)
17326 + if (old_addr != *(uint32_t *)addr_seg) {
17327 + int32_t offset = (field_id == 10) ? -2 : -6; /* offset from saddr or daddr */
17329 + csum_replace4((uint16_t *)(addr_seg + offset), old_addr, *(uint32_t *)addr_seg);
17331 + prot_offset = (field_id == 10) ? -3 : -7; /* offset from saddr or daddr */
17332 + protocol_seg = seg->start + seg->offset + prot_offset;
17334 + if (skb && (protocol_seg[0] == 0x06 || protocol_seg[0] == 0x11)) { /* is payload TCP or UDP ? */
17336 + check = seg->start + seg->offset; /* tmp res */
17337 + check += (field_id == 10) ? 8 : 16; /* the start of the payload, depending saddr or daddr */
17338 + check += (protocol_seg[0] == 0x06) ? 16 : 6; /* the start of the checksum, depending on TCP or UDP */
17340 + inet_proto_csum_replace4((__sum16 *)check, skb, old_addr, *(uint32_t *)addr_seg, 1);
17353 +static int32_t ip_addr_get(lua_State *L)
17355 + lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
17356 + uint8_t *addr_seg = seg->start + seg->offset;
17358 + char buf[16]; /*max: 255.255.255.255\0 --> 16 chars */
17360 + sprintf(buf, IP_FMT, IP_ACC(addr_seg));
17361 + lua_pushstring(L, buf);
17365 +static int32_t ip_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
17367 + uint8_t * embedded_protocol = seg->start + seg->offset + 9 /*bytes*/;
17369 + switch (embedded_protocol[0]) {
17370 + case 0x01: /* 1: Internet Control Message Protocol (ICMP) */
17371 + if (protocol_type == PACKET_ICMP) return 1;
17373 + case 0x02: /* 2: Internet Group Management Protocol (IGMP) */
17375 + case 0x06: /* 6: Transmission Control Protocol (TCP) */
17376 + if (protocol_type == PACKET_TCP) return 1;
17378 + case 0x11: /* 17: User Datagram Protocol (UDP) */
17379 + if (protocol_type == PACKET_UDP) return 1;
17381 + case 0x59: /* 89: Open Shortest Path First (OSPF) */
17383 + case 0x84: /* 132: Stream Control Transmission Protocol (SCTP) */
17392 +static const struct protocol_field ip_protocol_fields[] = {
17393 + /* field name offset length getter setter */
17394 + { "version", 0, 4, ip_version_get, ip_version_set },
17395 + { "ihl", 4, 4, ip_ihl_get, ip_ihl_set },
17396 + { "tos", 8, 8, get_8_bit_generic, set_8_bit_generic },
17397 + { "tot_len", 16, 16, get_16_bit_generic, set_16_bit_generic },
17398 + { "id", 32, 16, get_16_bit_generic, set_16_bit_generic },
17399 + { "flags", 48, 3, get_1_bit_generic, set_1_bit_generic },
17400 + { "frag_off", 51, 13, NULL, NULL },
17401 + { "ttl", 64, 8, get_8_bit_generic, set_8_bit_generic },
17402 + { "protocol", 72, 8, get_8_bit_generic, set_8_bit_generic },
17403 + { "check", 80, 16, get_16_bit_generic, set_16_bit_generic },
17404 + { "saddr", 96, 32, ip_addr_get, ip_addr_set },
17405 + { "daddr", 128, 32, ip_addr_get, ip_addr_set },
17406 + { "data", 160, 0, NULL, set_data_generic },
17407 + PROT_FIELD_SENTINEL,
17410 +static const struct protocol_buf ip_protocol_buf = {
17412 + .name = LUA_PACKET_SEG_IP,
17413 + .payload_field = "data",
17414 + .protocol_fields = (struct protocol_field *)&ip_protocol_fields,
17415 + .has_protocol = &ip_has_protocol,
17416 + .get_field_changes = NULL,
17419 +void luaopen_protbuf_ip(lua_State *L)
17421 + register_protbuf(L, (struct protocol_buf *)&ip_protocol_buf, PACKET_IP);
17425 +++ b/extensions/LUA/prot_buf_raw.c
17428 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17429 + * by Andre Graf <andre@dergraf.org>
17431 + * This program is free software; you can redistribute it and/or modify
17432 + * it under the terms of the GNU General Public License as published by
17433 + * the Free Software Foundation; either version 2 of the License, or
17434 + * (at your option) any later version.
17436 + * This program is distributed in the hope that it will be useful,
17437 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17438 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17439 + * GNU General Public License for more details.
17441 + * You should have received a copy of the GNU General Public License
17442 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17445 +#include "controller.h"
17446 +static int32_t raw_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
17451 +static const struct protocol_field raw_protocol_fields[] = {
17452 + /* field name offset length getter setter */
17453 + { "data", 0, 0, NULL, NULL },
17454 + PROT_FIELD_SENTINEL,
17457 +static const struct protocol_buf raw_protocol_buf = {
17459 + .name = LUA_PACKET_SEG_RAW,
17460 + .payload_field = "data",
17461 + .protocol_fields = (struct protocol_field *)&raw_protocol_fields,
17462 + .has_protocol = &raw_has_protocol,
17463 + .get_field_changes = NULL,
17466 +void luaopen_protbuf_raw(lua_State *L)
17468 + register_protbuf(L, (struct protocol_buf *)&raw_protocol_buf, PACKET_RAW);
17471 +++ b/extensions/LUA/prot_buf_tcp.c
17474 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17475 + * by Andre Graf <andre@dergraf.org>
17477 + * This program is free software; you can redistribute it and/or modify
17478 + * it under the terms of the GNU General Public License as published by
17479 + * the Free Software Foundation; either version 2 of the License, or
17480 + * (at your option) any later version.
17482 + * This program is distributed in the hope that it will be useful,
17483 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17484 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17485 + * GNU General Public License for more details.
17487 + * You should have received a copy of the GNU General Public License
17488 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17491 +#if defined(__KERNEL__)
17492 + #include <net/checksum.h>
17493 + #include <net/tcp.h>
17495 +#include "controller.h"
17498 +static int32_t tcp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
17503 +static int32_t tcp_set_checksum(lua_State *L)
17505 + struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
17506 + lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
17508 +#if defined(__KERNEL__)
17509 + uint8_t * check_seg = seg->start + seg->offset;
17510 + uint8_t * tcp_hdr = check_seg - 16;
17511 + uint8_t * saddr = tcp_hdr - 8;
17512 + uint8_t * daddr = saddr + 4;
17513 + uint32_t len = 20 + (seg->changes->field_length_changes[11] / 8) + (seg->changes->field_length_changes[10] / 8);
17514 + unsigned short checksum = tcp_v4_check(len, *(uint32_t *)saddr, *(uint32_t *)daddr,
17515 + csum_partial(tcp_hdr, len, 0));
17517 + memcpy(check_seg, &checksum, sizeof(unsigned short));
17523 +static const struct protocol_field tcp_protocol_fields[] = {
17524 + /* field name offset length getter setter */
17525 + { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
17526 + { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
17527 + { "seq", 32, 32, get_32_bit_generic, set_32_bit_generic },
17528 + { "ack", 64, 32, get_32_bit_generic, set_32_bit_generic },
17529 + { "data_off", 96, 4, get_lower_4_bit_generic, set_lower_4_bit_generic },
17530 + { "reserved", 100, 4, get_upper_4_bit_generic, set_upper_4_bit_generic },
17531 + { "flags", 104, 8, get_1_bit_generic, set_1_bit_generic },
17532 + { "window_size", 112, 16, get_16_bit_generic, set_16_bit_generic },
17533 + { "check", 128, 16, get_16_bit_generic, tcp_set_checksum },
17534 + { "urgent", 144, 16, NULL, NULL },
17535 + { "options", 160, 0, NULL, set_data_generic },
17536 + { "data", 160, 0, NULL, set_data_generic }, /* begin of data depends on options */
17537 + PROT_FIELD_SENTINEL,
17541 +static const struct protocol_field tcp_options_and_data[] = {
17542 + /* field name offset length getter setter */
17543 + { "MSS", 0, 16, get_16_bit_generic, set_16_bit_generic },
17544 + { "WS", 0, 8, get_8_bit_generic, set_8_bit_generic },
17545 + { "SACK", 0, 16, get_16_bit_generic, set_16_bit_generic },
17546 + { "TSVAL", 0, 32, get_32_bit_generic, set_32_bit_generic },
17547 + { "TSER", 0, 32, get_32_bit_generic, set_32_bit_generic },
17548 + PROT_FIELD_SENTINEL,
17552 +static struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg);
17554 +static const struct protocol_buf tcp_protocol_buf = {
17556 + .name = LUA_PACKET_SEG_TCP,
17557 + .payload_field = "data",
17558 + .protocol_fields = (struct protocol_field *)&tcp_protocol_fields,
17559 + .has_protocol = &tcp_has_protocol,
17560 + .get_field_changes = &tcp_get_field_changes,
17564 +static struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg);
17566 +static const struct protocol_buf tcp_options_and_data_buf = {
17568 + .name = LUA_PACKET_SEG_TCP_OPT,
17569 + .payload_field = NULL,
17570 + .protocol_fields = (struct protocol_field *)&tcp_options_and_data,
17571 + .has_protocol = NULL,
17572 + .get_field_changes = &tcp_options_get_field_changes,
17575 +struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg)
17577 + /* depending on the value stored inside the 'data_off'-field, the length of
17578 + * the 'options' field has to be changed, as well as the length and offset
17579 + * of the 'data' field */
17580 + uint8_t *tcp_hdr = seg->start + seg->offset;
17582 + /* get the pointer to the 'data_off' field */
17583 + uint8_t * data_off_field = tcp_hdr + 12; /* 12 bytes offset */
17584 + /* extract the stored header length in bits */
17585 + uint32_t tcp_hdr_len = ((*(uint8_t *)data_off_field) >> 4) * 32;
17587 + /* get an allocated 'field_changes' structure */
17588 + struct field_changes * changes = get_allocated_field_changes(L, 12);
17590 + /* depending on the tcp header length, change the length of the options*/
17591 + changes->field_length_changes[10] = tcp_hdr_len - 160;
17592 + /* depending on the options length, change the offset of the data */
17593 + changes->field_offset_changes[11] = changes->field_length_changes[10];
17594 + changes->field_length_changes[11] = (seg->length * 8) - tcp_hdr_len;
17600 +struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg)
17602 + /* depending on the value stored inside the 'data_off'-field, the length of
17603 + * the 'options' field has to be changed, as well as the length and offset
17604 + * of the 'data' field */
17605 + uint8_t *tcp_opt_hdr = seg->start + seg->offset;
17607 + /* get an allocated 'field_changes' structure */
17608 + struct field_changes * changes = get_allocated_field_changes(L, 5);
17610 + int32_t MSS = 0, WS = 0, SACK = 0, TS = 0, i;
17614 + for (i = 0; i < seg->length; i++) {
17615 + b1 = tcp_opt_hdr[i];
17616 + b2 = tcp_opt_hdr[i + 1];
17621 + /* test for MSS */
17622 + if (!MSS && (b1 == 0x02 && b2 == 0x04)) {
17623 + changes->field_offset_changes[0] = (i + 2) * CHAR_BIT;
17627 + /* test for WS --- yet buggy somehow */
17628 + if (!WS && (b1 == 0x03 && b2 == 0x03)) {
17629 + changes->field_offset_changes[1] = (i + 2) * CHAR_BIT;
17633 + /* test for SACK*/
17634 + if (!SACK && (b1 == 0x04 && b2 == 0x02)) {
17635 + changes->field_offset_changes[2] = i * CHAR_BIT; /* has no value */
17639 + /* test for TS */
17640 + if (!TS && (b1 == 0x08 && b2 == 0x0A)) {
17641 + changes->field_offset_changes[3] = (i + 2) * CHAR_BIT;
17642 + changes->field_offset_changes[4] = (i + 2 + 4) * CHAR_BIT;
17651 +void luaopen_protbuf_tcp(lua_State *L)
17653 + register_protbuf(L, (struct protocol_buf *)&tcp_protocol_buf, PACKET_TCP);
17655 +void luaopen_protbuf_tcp_options(lua_State *L)
17657 + register_protbuf(L, (struct protocol_buf *)&tcp_options_and_data_buf, PACKET_TCP_OPTIONS);
17662 +++ b/extensions/LUA/prot_buf_tftp.c
17665 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17666 + * by Andre Graf <andre@dergraf.org>
17668 + * This program is free software; you can redistribute it and/or modify
17669 + * it under the terms of the GNU General Public License as published by
17670 + * the Free Software Foundation; either version 2 of the License, or
17671 + * (at your option) any later version.
17673 + * This program is distributed in the hope that it will be useful,
17674 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17675 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17676 + * GNU General Public License for more details.
17678 + * You should have received a copy of the GNU General Public License
17679 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17681 +#include "controller.h"
17683 +static const struct protocol_field tftp_protocol_fields[] = {
17684 + /* field name offset length getter setter */
17685 + { "opcode", 0, 16, get_16_bit_generic, NULL},
17686 + { "filename", 0, 0, get_string_generic, NULL},
17687 + { "mode", 0, 0, get_string_generic, NULL},
17688 + { "block_nr", 0, 16, get_16_bit_generic, NULL},
17689 + { "data", 0, 0, NULL, NULL},
17690 + PROT_FIELD_SENTINEL,
17693 +struct field_changes * tftp_get_field_changes(lua_State *L, lua_packet_segment * seg)
17695 + /* depending on the value stored inside the 'opcode'-field we have to change
17696 + * offsets and lengths */
17697 + uint8_t *tftp_hdr = seg->start + seg->offset;
17698 + short opcode = ntohs(*((uint16_t *)tftp_hdr));
17699 + /* get an allocated 'field_changes' structure */
17700 + struct field_changes * changes = get_allocated_field_changes(L, 5);
17701 + switch (opcode) {
17702 + case 1: /* Read Request (RRQ) */
17703 + /* setting offset and length of field 'filename' */
17704 + changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
17705 + changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
17706 + /* setting offset and length of field 'mode' */
17707 + changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
17708 + changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
17710 + case 2: /* Write Request (WRQ) */
17711 + /* setting offset and length of field 'filename' */
17712 + changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
17713 + changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
17714 + /* setting offset and length of field 'mode' */
17715 + changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
17716 + changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
17718 + case 3: /* Data (DATA) */
17719 + /* setting offset of field 'block_nr' */
17720 + changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
17721 + /* setting offset of field 'data' */
17722 + changes->field_offset_changes[4] = changes->field_offset_changes[3] + (sizeof(unsigned short) << 3);
17724 + case 4: /* Acknowledgment (ACK) */
17725 + /* setting offset of field 'block_nr' */
17726 + changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
17728 + case 5: /* Error (ERROR) */
17729 + /* we don't care ... yet */
17738 +static const struct protocol_buf tftp_protocol_buf = {
17740 + .name = LUA_PACKET_SEG_TFTP,
17741 + .payload_field = NULL,
17742 + .protocol_fields = (struct protocol_field *)&tftp_protocol_fields,
17743 + .has_protocol = NULL, /* we don't need it, since we don't provide a payload field */
17744 + .get_field_changes = tftp_get_field_changes,
17747 +void luaopen_protbuf_tftp(lua_State *L)
17749 + register_protbuf(L, (struct protocol_buf *)&tftp_protocol_buf, PACKET_TFTP);
17752 +++ b/extensions/LUA/prot_buf_udp.c
17755 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17756 + * by Andre Graf <andre@dergraf.org>
17758 + * This program is free software; you can redistribute it and/or modify
17759 + * it under the terms of the GNU General Public License as published by
17760 + * the Free Software Foundation; either version 2 of the License, or
17761 + * (at your option) any later version.
17763 + * This program is distributed in the hope that it will be useful,
17764 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17765 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17766 + * GNU General Public License for more details.
17768 + * You should have received a copy of the GNU General Public License
17769 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17772 +#if defined(__KERNEL__)
17773 + #include <net/checksum.h>
17776 +#include "controller.h"
17779 +static int32_t udp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
17784 +static const struct protocol_field udp_protocol_fields[] = {
17785 + /* field name offset length getter setter */
17786 + { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
17787 + { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
17788 + { "length", 32, 16, get_16_bit_generic, set_16_bit_generic },
17789 + { "check", 48, 16, get_16_bit_generic, set_16_bit_generic },
17790 + { "data", 64, 0, NULL, NULL },
17791 + PROT_FIELD_SENTINEL,
17794 +static const struct protocol_buf udp_protocol_buf = {
17796 + .name = LUA_PACKET_SEG_UDP,
17797 + .payload_field = "data",
17798 + .protocol_fields = (struct protocol_field *)&udp_protocol_fields,
17799 + .has_protocol = &udp_has_protocol,
17800 + .get_field_changes = NULL,
17803 +void luaopen_protbuf_udp(lua_State *L)
17805 + register_protbuf(L, (struct protocol_buf *)&udp_protocol_buf, PACKET_UDP);
17808 +++ b/extensions/LUA/xt_LUA.h
17811 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17812 + * by Andre Graf <andre.graf@stud.unibas.ch>
17814 + * This program is free software; you can redistribute it and/or modify
17815 + * it under the terms of the GNU General Public License as published by
17816 + * the Free Software Foundation; either version 2 of the License, or
17817 + * (at your option) any later version.
17819 + * This program is distributed in the hope that it will be useful,
17820 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17821 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17822 + * GNU General Public License for more details.
17824 + * You should have received a copy of the GNU General Public License
17825 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17831 +#define MAX_FILENAME_SIZE 256
17832 +#define MAX_FUNCTION_SIZE 256
17833 +#define MAX_SCRIPT_SIZE 32768
17834 +#define LUA_STATE_ARRAY_SIZE 128
17836 +/* the targetsize is stored in a u16, so max size of the xt_lua_tginfo cannot exceed 64K*/
17837 +struct xt_lua_tginfo {
17838 + char buf[MAX_SCRIPT_SIZE];
17839 + char filename[MAX_FILENAME_SIZE];
17840 + char function[MAX_FUNCTION_SIZE];
17841 + __u64 script_size;
17845 +#endif /* XT_LUA_H_ */
17847 +++ b/extensions/LUA/xt_LUA.mod.c
17849 +#include <linux/module.h>
17850 +#include <linux/vermagic.h>
17851 +#include <linux/compiler.h>
17853 +MODULE_INFO(vermagic, VERMAGIC_STRING);
17855 +struct module __this_module
17856 +__attribute__((section(".gnu.linkonce.this_module"))) = {
17857 + .name = KBUILD_MODNAME,
17858 + .init = init_module,
17859 +#ifdef CONFIG_MODULE_UNLOAD
17860 + .exit = cleanup_module,
17862 + .arch = MODULE_ARCH_INIT,
17865 +static const struct modversion_info ____versions[]
17867 +__attribute__((section("__versions"))) = {
17868 + { 0xa3379c4b, "module_layout" },
17869 + { 0x5cf97727, "xt_unregister_target" },
17870 + { 0x9a1dfd65, "strpbrk" },
17871 + { 0x56fb5417, "kmalloc_caches" },
17872 + { 0x12da5bb2, "__kmalloc" },
17873 + { 0xb85f3bbe, "pv_lock_ops" },
17874 + { 0x349cba85, "strchr" },
17875 + { 0xd0d8621b, "strlen" },
17876 + { 0x79aa04a2, "get_random_bytes" },
17877 + { 0x20000329, "simple_strtoul" },
17878 + { 0x105e2727, "__tracepoint_kmalloc" },
17879 + { 0xbf7e1481, "inet_proto_csum_replace4" },
17880 + { 0x6c1ce5ce, "strcspn" },
17881 + { 0x3c2c5af5, "sprintf" },
17882 + { 0xe2d5255a, "strcmp" },
17883 + { 0xe24d3a97, "jiffies_64" },
17884 + { 0x2bc95bd4, "memset" },
17885 + { 0x87fc9bcc, "kmem_cache_alloc_notrace" },
17886 + { 0x11089ac7, "_ctype" },
17887 + { 0x37befc70, "jiffies_to_msecs" },
17888 + { 0x70d1f8f3, "strncat" },
17889 + { 0xb72397d5, "printk" },
17890 + { 0x42224298, "sscanf" },
17891 + { 0x5152e605, "memcmp" },
17892 + { 0xb6ed1e53, "strncpy" },
17893 + { 0x1e6d26a8, "strstr" },
17894 + { 0xc3fa6a59, "memchr" },
17895 + { 0x61651be, "strcat" },
17896 + { 0x7d8c0d13, "xt_register_target" },
17897 + { 0x8ff4079b, "pv_irq_ops" },
17898 + { 0x93fca811, "__get_free_pages" },
17899 + { 0xf0fdf6cb, "__stack_chk_fail" },
17900 + { 0xbbe2391b, "kfree_skb" },
17901 + { 0xf333a2fb, "_raw_spin_lock_irq" },
17902 + { 0x37a0cba, "kfree" },
17903 + { 0x2e60bace, "memcpy" },
17904 + { 0x59e7cb79, "skb_make_writable" },
17905 + { 0xb742fd7, "simple_strtol" },
17906 + { 0x7d50a24, "csum_partial" },
17907 + { 0xc2d711e1, "krealloc" },
17908 + { 0xe914e41e, "strcpy" },
17911 +static const char __module_depends[]
17913 +__attribute__((section(".modinfo"))) =
17914 +"depends=x_tables";
17917 +MODULE_INFO(srcversion, "33A1481C4AA71D1B5A8CA8A");
17919 +++ b/extensions/LUA/xt_LUA_target.c
17922 + * Copyright (C) 2010 University of Basel <http://cn.cs.unibas.ch/>
17923 + * by Andre Graf <andre@dergraf.org>
17925 + * This program is free software; you can redistribute it and/or modify
17926 + * it under the terms of the GNU General Public License as published by
17927 + * the Free Software Foundation; either version 2 of the License, or
17928 + * (at your option) any later version.
17930 + * This program is distributed in the hope that it will be useful,
17931 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17932 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17933 + * GNU General Public License for more details.
17935 + * You should have received a copy of the GNU General Public License
17936 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
17939 +#include <linux/kernel.h>
17940 +#include <linux/slab.h>
17941 +#include <linux/module.h>
17942 +#include <asm/uaccess.h>
17943 +#include <net/ip.h>
17944 +#include <linux/netfilter/x_tables.h>
17945 +#include "xt_LUA.h"
17947 +#include "controller.h"
17952 + * This array holds a defined number of `lua_envs`_ structures.
17953 + * The used array index is also used as the Lua state identifier.
17954 + * The size of the array is defined in `LUA_STATE_ARRAY_SIZE`_.
17956 +struct lua_env * lua_envs[LUA_STATE_ARRAY_SIZE];
17961 + * This array holds the reference counts of the several `lua_nf_state`_s
17962 + * which are stored inside the array `lua_states`_.
17964 +uint32_t lua_state_refs[LUA_STATE_ARRAY_SIZE] = { 0 };
17969 + * This function is called whenever a packet matches all matching conditions
17970 + * inside a rule. It is the target. It extracts the state identifier comming
17971 + * inside the *xt_target_param* structure and uses it to access the proper
17972 + * Lua state inside the `lua_states`_ array.
17974 + * It then constructs a new Lua userdata of type *lua_packet_segment* and
17975 + * initializes it with the lowest network header available. This userdata
17976 + * is annotated with the Lua metatable `LUA_PACKET_SEG_RAW`_ which converts
17977 + * the userdata to a raw lua packet having all raw functions available.
17978 + * This raw packet is the single parameter to the Lua function *process_packet*
17979 + * which must be defined inside the Lua script provided by the user. So far
17980 + * hardcoded, may be later configured by Lua - subject to change.
17982 + * The process_packet function must return an integer value, the verdict. For
17983 + * convenience reasons xt_LUA exports the verdicts NF_ACCEPT, NF_DROP and
17984 + * XT_CONTINUE inside the *register_lua_packet_lib* function.
17987 +spinlock_t lock = SPIN_LOCK_UNLOCKED;
17990 +lua_tg(struct sk_buff *pskb, const struct xt_target_param *par)
17992 + uint32_t verdict;
17993 + lua_packet_segment *p;
17994 + const struct xt_lua_tginfo *info = par->targinfo;
17997 + /* START critical section on SMP, PacketScript is on the sequential trail at the moment TODO*/
17998 + spin_lock_irq(&lock);
18000 + L = lua_envs[info->state_id]->L;
18002 + if (!skb_make_writable(pskb, pskb->len))
18005 + /* call the function provided by --function parameter or the default 'process_packet' defined in Lua */
18006 + lua_getglobal(L, info->function);
18008 + /* push the lua_packet_segment as a parameter */
18009 + p = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
18010 + if (pskb->mac_header)
18011 + p->start = pskb->mac_header;
18012 + else if (pskb->network_header)
18013 + p->start = pskb->network_header;
18014 + else if (pskb->transport_header)
18015 + p->start = pskb->transport_header;
18017 + p->length = (unsigned long)pskb->tail - (unsigned long)p->start;
18018 + p->changes = NULL;
18020 + /* marking userdata 'lua_packet_seg' with the corresponding metatable */
18021 + luaL_getmetatable(L, LUA_PACKET_SEG_RAW);
18022 + lua_setmetatable(L, -2);
18024 + /* push a reference to the skb as a parameter, needed at the moment for calculating TCP checksum, but I am not happy with it*/
18025 + lua_pushlightuserdata(L, (void *)skb_get(pskb));
18027 + /* do the function call (2 argument, 1 result) */
18028 + if (lua_pcall(L, 2, 1, 0) != 0) {
18029 + printk(KERN_ERR "LUA [%d]: pcall '%s' failed: %s\n", info->state_id, info->function, lua_tostring(L, -1));
18034 + if (!lua_isnumber(L, -1)) {
18035 + printk(KERN_ERR "LUA [%d]: function '%s' must return a verdict\n", info->state_id, info->function);
18040 + verdict = lua_tonumber(L, -1);
18045 + /* END critical section on SMP */
18046 + spin_unlock_irq(&lock);
18052 +/* Helper for checkentry */
18053 +static bool load_script_into_state(uint32_t state_id, unsigned long script_size, char *script_buf)
18055 + char *buf = kmalloc(script_size, GFP_KERNEL);
18057 + struct lua_env * env = kmalloc(sizeof(struct lua_env), GFP_KERNEL);
18059 + if (!script_size > 0) {
18060 + pr_debug("LUA [%d]: script_size %lu < 0\n", state_id, script_size);
18064 + env->L = lua_open();
18065 + luaopen_base(env->L);
18066 + luaopen_controller(env->L);
18068 + lua_getglobal(env->L, "_G");
18069 + lua_pushinteger(env->L, state_id);
18070 + lua_setfield(env->L, -2, "STATE_ID");
18071 + lua_pop(env->L, 1); /* pop _G */
18073 + strncpy(buf, script_buf, script_size);
18074 + ret = luaL_loadbuffer(env->L, buf, script_size, "PacketScript, loadbuffer") ||
18075 + lua_pcall(env->L, 0, 1, 0);
18078 + printk(KERN_ERR "LUA [%d]: failure loading script, error %s \n", state_id, lua_tostring(env->L, -1));
18079 + lua_pop(env->L, 1);
18085 + lua_envs[state_id] = env;
18092 + * lua_tg_checkentry
18093 + * -----------------
18094 + * This function is used as a kernel-side sanity check of the data comming
18095 + * from the iptables userspace program. Since this is the function which is
18096 + * called everytime a new rule (with -j xt_LUA) is injected, this function
18097 + * is used to do the bookkeeping work, such as counting the reference of
18098 + * several Lua states and the initialization of new states if needed. As an
18099 + * extra initialization step it loads the provided Lua script into the Lua
18102 + * Lua state initialization
18103 + * ~~~~~~~~~~~~~~~~~~~~~~~~
18104 + * 1. If a new rule is inserted and there is no existing state for the given
18105 + * state identifier (default state identifier is 0) a new Lua state is
18106 + * initialized using *lua_open*.
18107 + * 2. The Lua base library is registered inside the newly initialized state.
18108 + * Have a look at *lua/lbaselib.c* to see what functions of the Lua base
18109 + * library are available inside Lua.
18110 + * 3. The Lua packet library is registered inside the Lua state using the
18111 + * function *register_lua_packet_lib*. So far this function only registers
18112 + * the Netfilter verdicts NF_ACCEPT, NF_DROP and XT_CONTINUE inside the
18113 + * global environment of the given Lua state.
18114 + * 4. All the protocol Buffers, and the functions for accessing the bytes are
18115 + * registered using *register_protocols*.
18117 + * Lua state reference counting
18118 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18119 + * Bookkeeping of the Lua states inside the *lua_state_refs* array. The
18120 + * state identifier is mapped to the array index, which holds an integer
18121 + * counting the several initialized states.
18123 + * Loading the Lua script
18124 + * ~~~~~~~~~~~~~~~~~~~~~~
18125 + * Copying the buffer which was initialized by the userspace program to a
18126 + * buffer with the proper size. The script is then loaded by the function
18127 + * xt_LUA_loadcode, which wrapps the *luaL_loadbuffer* function and does
18128 + * some workqueue initialization. So far this is done each time this function
18129 + * is called, subject to change.
18132 +lua_tg_checkentry(const struct xt_tgchk_param *par)
18134 + const struct xt_lua_tginfo *info = par->targinfo;
18136 + if (load_script_into_state(info->state_id, info->script_size, (char *)info->buf)) {
18137 + lua_state_refs[info->state_id]++;
18146 + * This function is the counterpart of the `lua_tg_checkentry`_ function. It is
18147 + * responsible to free all the resources alocated inside the checkentry process.
18148 + * To be more specific it frees the Lua state using *lua_close* and kfree on all
18149 + * the dynamically allocated pointers to the registered dynamic protocol buffers.
18151 + * Additionally the function cares about decrementing the reference counters
18152 + * inside the array `lua_states`_.
18155 +lua_tg_destroy(const struct xt_tgdtor_param *par)
18157 + const struct xt_lua_tginfo *info = par->targinfo;
18158 + struct lua_env * env = lua_envs[info->state_id];
18160 + if (lua_state_refs[info->state_id] == 1) {
18161 + lua_close(env->L);
18162 + cleanup_dynamic_prot_bufs(); /* clean memory allocated by protocols defined in Lua */
18164 + pr_debug("LUA [%d]: Rule removed, close Lua state\n", info->state_id);
18166 + pr_debug("LUA [%d]: Rule removed, Lua state stays open, referenced %d time(s)\n",
18167 + info->state_id, lua_state_refs[info->state_id] - 1);
18169 + lua_state_refs[info->state_id]--;
18172 +static struct xt_target lua_tg_reg __read_mostly = {
18175 + .family = NFPROTO_UNSPEC,
18176 + .targetsize = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
18177 + .target = lua_tg,
18178 + .checkentry = lua_tg_checkentry,
18179 + .destroy = lua_tg_destroy,
18180 + .me = THIS_MODULE,
18184 +static int32_t lua_tg_init(void)
18186 + return xt_register_target(&lua_tg_reg);
18189 +static void lua_tg_exit(void)
18191 + xt_unregister_target(&lua_tg_reg);
18194 +module_init(lua_tg_init);
18195 +module_exit(lua_tg_exit);
18197 +MODULE_AUTHOR("Andre Graf <andre@dergraf.org>");
18198 +MODULE_DESCRIPTION("Xtables: Processing of matched packets using the Lua scripting environment");
18199 +MODULE_ALIAS("ipt_LUA");
18200 +MODULE_ALIAS("ipt6t_LUA");
18201 +MODULE_ALIAS("arpt_LUA");
18202 +MODULE_ALIAS("ebt_LUA");
18203 +MODULE_LICENSE("GPL");
18207 --- a/extensions/Kbuild
18208 +++ b/extensions/Kbuild
18209 @@ -34,6 +34,7 @@ obj-${build_pknock} += pknock/
18210 obj-${build_psd} += xt_psd.o
18211 obj-${build_quota2} += xt_quota2.o
18212 obj-${build_rtsp} += rtsp/
18213 +obj-${build_LUA} += LUA/
18215 -include ${M}/*.Kbuild
18216 -include ${M}/Kbuild.*
18217 --- a/extensions/Mbuild
18218 +++ b/extensions/Mbuild
18219 @@ -24,3 +24,4 @@ obj-${build_pknock} += pknock/
18220 obj-${build_psd} += libxt_psd.so
18221 obj-${build_quota2} += libxt_quota2.so
18222 obj-${build_gradm} += libxt_gradm.so
18223 +obj-${build_LUA} += LUA/
18226 @@ -25,3 +25,4 @@ build_pknock=m