diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-04 08:47:49 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-04 08:47:49 -0200 |
commit | c635044f2f0fc6a3cc19b720668b8bd8f61b5134 (patch) | |
tree | b62f6a3826dc45a833cffcc09a93f38ad1e0c8d5 /opcode.c | |
parent | 3db06a95a388c2e0922fd138434321240a4eb075 (diff) | |
download | lua-c635044f2f0fc6a3cc19b720668b8bd8f61b5134.tar.gz lua-c635044f2f0fc6a3cc19b720668b8bd8f61b5134.tar.bz2 lua-c635044f2f0fc6a3cc19b720668b8bd8f61b5134.zip |
creation of function do_protectedrun, that executes lua code enclosed
in a setjmp, with error recovery.
Elimination of functions lua_isnil, etc.
Diffstat (limited to 'opcode.c')
-rw-r--r-- | opcode.c | 316 |
1 files changed, 96 insertions, 220 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 2.12 1994/11/01 18:25:20 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
@@ -30,27 +30,36 @@ static Long maxstack; | |||
30 | static Object *stack=NULL; | 30 | static Object *stack=NULL; |
31 | static Object *top; | 31 | static Object *top; |
32 | 32 | ||
33 | static int CBase; /* when Lua calls C or C calls Lua, points to the */ | 33 | |
34 | /* first slot after the last parameter. */ | 34 | static int CBase = 0; /* when Lua calls C or C calls Lua, points to the */ |
35 | /* first slot after the last parameter. */ | ||
35 | static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ | 36 | static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ |
36 | /* when C calls Lua, has the number of results. */ | 37 | /* when C calls Lua, has the number of results. */ |
38 | |||
39 | static jmp_buf *errorJmp = NULL; /* current error recover point */ | ||
37 | 40 | ||
38 | static jmp_buf *errorJmp; | ||
39 | 41 | ||
40 | static int lua_execute (Byte *pc, int base); | 42 | static int lua_execute (Byte *pc, int base); |
41 | 43 | ||
42 | 44 | ||
45 | static void lua_message (char *s) | ||
46 | { | ||
47 | fprintf (stderr, "lua: %s\n", s); | ||
48 | } | ||
43 | 49 | ||
44 | /* | 50 | /* |
45 | ** Reports an error, and jumps up to the available recover label | 51 | ** Reports an error, and jumps up to the available recover label |
46 | */ | 52 | */ |
47 | void lua_error (char *s) | 53 | void lua_error (char *s) |
48 | { | 54 | { |
49 | fprintf (stderr, "lua: %s\n", s); | 55 | lua_message(s); |
50 | if (errorJmp) | 56 | if (errorJmp) |
51 | longjmp(*errorJmp, 1); | 57 | longjmp(*errorJmp, 1); |
52 | else | 58 | else |
59 | { | ||
60 | fprintf (stderr, "lua: exit(1). Unable to recover\n"); | ||
53 | exit(1); | 61 | exit(1); |
62 | } | ||
54 | } | 63 | } |
55 | 64 | ||
56 | 65 | ||
@@ -73,7 +82,7 @@ static void lua_initstack (void) | |||
73 | static void lua_checkstack (Word n) | 82 | static void lua_checkstack (Word n) |
74 | { | 83 | { |
75 | if (stack == NULL) | 84 | if (stack == NULL) |
76 | return lua_initstack(); | 85 | lua_initstack(); |
77 | if (n > maxstack) | 86 | if (n > maxstack) |
78 | { | 87 | { |
79 | int t = top-stack; | 88 | int t = top-stack; |
@@ -99,12 +108,6 @@ static char *lua_strconc (char *l, char *r) | |||
99 | return strcat(strcpy(buffer,l),r); | 108 | return strcat(strcpy(buffer,l),r); |
100 | } | 109 | } |
101 | 110 | ||
102 | static int ToReal (char* s, float* f) | ||
103 | { | ||
104 | char c; | ||
105 | float t; | ||
106 | if (sscanf(s,"%f %c",&t,&c) == 1) { *f=t; return 1; } else return 0; | ||
107 | } | ||
108 | 111 | ||
109 | /* | 112 | /* |
110 | ** Convert, if possible, to a number object. | 113 | ** Convert, if possible, to a number object. |
@@ -112,31 +115,18 @@ static int ToReal (char* s, float* f) | |||
112 | */ | 115 | */ |
113 | static int lua_tonumber (Object *obj) | 116 | static int lua_tonumber (Object *obj) |
114 | { | 117 | { |
118 | char c; | ||
119 | float t; | ||
115 | if (tag(obj) != LUA_T_STRING) | 120 | if (tag(obj) != LUA_T_STRING) |
116 | return 1;; | 121 | return 1; |
117 | if (!ToReal(svalue(obj), &nvalue(obj))) | 122 | else if (sscanf(svalue(obj), "%f %c",&t,&c) == 1) |
118 | return 2; | ||
119 | tag(obj) = LUA_T_NUMBER; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | ** Test if it is possible to convert an object to a number object. | ||
125 | ** If possible, return the converted object, otherwise return nil object. | ||
126 | */ | ||
127 | static Object *lua_convtonumber (Object *obj) | ||
128 | { | ||
129 | static Object cvt; | ||
130 | if (tag(obj) == LUA_T_NUMBER) | ||
131 | { | 123 | { |
132 | cvt = *obj; | 124 | nvalue(obj) = t; |
133 | return &cvt; | 125 | tag(obj) = LUA_T_NUMBER; |
126 | return 0; | ||
134 | } | 127 | } |
135 | if (tag(obj) == LUA_T_STRING && ToReal(svalue(obj), &nvalue(&cvt))) | ||
136 | tag(&cvt) = LUA_T_NUMBER; | ||
137 | else | 128 | else |
138 | tag(&cvt) = LUA_T_NIL; | 129 | return 2; |
139 | return &cvt; | ||
140 | } | 130 | } |
141 | 131 | ||
142 | 132 | ||
@@ -182,7 +172,8 @@ static int callC (lua_CFunction func, int base) | |||
182 | int oldCnResults = CnResults; | 172 | int oldCnResults = CnResults; |
183 | int firstResult; | 173 | int firstResult; |
184 | CnResults = (top-stack) - base; | 174 | CnResults = (top-stack) - base; |
185 | CBase = base+CnResults; /* incorporate parameters on the stack */ | 175 | /* incorporate parameters on the stack */ |
176 | CBase = base+CnResults; | ||
186 | (*func)(); | 177 | (*func)(); |
187 | firstResult = CBase; | 178 | firstResult = CBase; |
188 | CBase = oldBase; | 179 | CBase = oldBase; |
@@ -221,22 +212,17 @@ static void do_call (Object *func, int base, int nResults, int whereRes) | |||
221 | 212 | ||
222 | 213 | ||
223 | /* | 214 | /* |
224 | ** Function to index the values on the top | 215 | ** Function to index a table. Receives the table at top-2 and the index |
216 | ** at top-1. Remove them from stack and push the result. | ||
225 | */ | 217 | */ |
226 | int lua_pushsubscript (void) | 218 | static void pushsubscript (void) |
227 | { | 219 | { |
228 | --top; | 220 | Object *h; |
229 | if (tag(top-1) != LUA_T_ARRAY) | 221 | if (tag(top-2) != LUA_T_ARRAY) |
230 | { | 222 | lua_reportbug ("indexed expression not a table"); |
231 | lua_reportbug ("indexed expression not a table"); | 223 | h = lua_hashget (avalue(top-2), top-1); |
232 | return 1; | 224 | --top; |
233 | } | ||
234 | { | ||
235 | Object *h = lua_hashget (avalue(top-1), top); | ||
236 | if (h == NULL) return 1; | ||
237 | *(top-1) = *h; | 225 | *(top-1) = *h; |
238 | } | ||
239 | return 0; | ||
240 | } | 226 | } |
241 | 227 | ||
242 | 228 | ||
@@ -272,89 +258,89 @@ void lua_travstack (void (*fn)(Object *)) | |||
272 | 258 | ||
273 | 259 | ||
274 | /* | 260 | /* |
275 | ** Executes a main procedure. Uses as Base the top of the stack, as it | 261 | ** Execute a protected call. If function is null compiles the pre-set input. |
276 | ** uses no parameters and left no results. | 262 | ** Leave nResults on the stack. |
277 | */ | 263 | */ |
278 | static void do_main (Byte *main) | 264 | static int do_protectedrun (Object *function, int nResults) |
279 | { | ||
280 | if (main) | ||
281 | { | ||
282 | Object f; | ||
283 | tag(&f) = LUA_T_FUNCTION; bvalue(&f) = main; | ||
284 | do_call(&f, top-stack, 0, top-stack); | ||
285 | free(main); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | |||
290 | /* | ||
291 | ** Open file, generate opcode and execute global statement. Return 0 on | ||
292 | ** success or 1 on error. | ||
293 | */ | ||
294 | int lua_dofile (char *filename) | ||
295 | { | 265 | { |
266 | Object f; | ||
296 | jmp_buf myErrorJmp; | 267 | jmp_buf myErrorJmp; |
297 | int status; | 268 | int status; |
269 | int oldCBase = CBase; | ||
298 | jmp_buf *oldErr = errorJmp; | 270 | jmp_buf *oldErr = errorJmp; |
299 | errorJmp = &myErrorJmp; | 271 | errorJmp = &myErrorJmp; |
300 | if (setjmp(myErrorJmp) == 0) | 272 | if (setjmp(myErrorJmp) == 0) |
301 | { | 273 | { |
302 | lua_openfile (filename); | 274 | if (function == NULL) |
303 | do_main(lua_parse()); | 275 | { |
276 | function = &f; | ||
277 | tag(function) = LUA_T_FUNCTION; | ||
278 | bvalue(function) = lua_parse(); | ||
279 | } | ||
280 | do_call(function, CBase, nResults, CBase); | ||
281 | CnResults = (top-stack) - CBase; /* number of results */ | ||
282 | CBase += CnResults; /* incorporate results on the stack */ | ||
304 | status = 0; | 283 | status = 0; |
305 | } | 284 | } |
306 | else | 285 | else |
286 | { | ||
287 | CBase = oldCBase; | ||
288 | top = stack+CBase; | ||
307 | status = 1; | 289 | status = 1; |
308 | lua_closefile(); | 290 | } |
309 | errorJmp = oldErr; | 291 | errorJmp = oldErr; |
310 | return status; | 292 | return status; |
311 | } | 293 | } |
312 | 294 | ||
313 | /* | 295 | /* |
314 | ** Generate opcode stored on string and execute global statement. Return 0 on | 296 | ** Execute the given lua function. Return 0 on success or 1 on error. |
297 | */ | ||
298 | int lua_callfunction (Object *function) | ||
299 | { | ||
300 | if (function == NULL) | ||
301 | return 1; | ||
302 | else | ||
303 | return do_protectedrun (function, MULT_RET); | ||
304 | } | ||
305 | |||
306 | |||
307 | /* | ||
308 | ** Open file, generate opcode and execute global statement. Return 0 on | ||
315 | ** success or 1 on error. | 309 | ** success or 1 on error. |
316 | */ | 310 | */ |
317 | int lua_dostring (char *string) | 311 | int lua_dofile (char *filename) |
318 | { | 312 | { |
319 | jmp_buf myErrorJmp; | ||
320 | int status; | 313 | int status; |
321 | jmp_buf *oldErr = errorJmp; | 314 | char *message = lua_openfile (filename); |
322 | errorJmp = &myErrorJmp; | 315 | if (message) |
323 | if (setjmp(myErrorJmp) == 0) | ||
324 | { | 316 | { |
325 | lua_openstring(string); | 317 | lua_message(message); |
326 | do_main(lua_parse()); | 318 | return 1; |
327 | status = 0; | ||
328 | } | 319 | } |
329 | else | 320 | status = do_protectedrun(NULL, 0); |
330 | status = 1; | 321 | lua_closefile(); |
331 | lua_closestring(); | ||
332 | errorJmp = oldErr; | ||
333 | return status; | 322 | return status; |
334 | } | 323 | } |
335 | 324 | ||
336 | /* | 325 | /* |
337 | ** Execute the given lua function. Return 0 on success or 1 on error. | 326 | ** Generate opcode stored on string and execute global statement. Return 0 on |
327 | ** success or 1 on error. | ||
338 | */ | 328 | */ |
339 | int lua_callfunction (Object *function) | 329 | int lua_dostring (char *string) |
340 | { | 330 | { |
341 | jmp_buf myErrorJmp; | ||
342 | int status; | 331 | int status; |
343 | jmp_buf *oldErr = errorJmp; | 332 | char *message = lua_openstring(string); |
344 | errorJmp = &myErrorJmp; | 333 | if (message) |
345 | if (setjmp(myErrorJmp) == 0) | ||
346 | { | 334 | { |
347 | do_call(function, CBase, MULT_RET, CBase); | 335 | lua_message(message); |
348 | CnResults = (top-stack) - CBase; /* number of results */ | 336 | return 1; |
349 | CBase += CnResults; /* incorporate results on the stack */ | ||
350 | status = 0; | ||
351 | } | 337 | } |
352 | else | 338 | status = do_protectedrun(NULL, 0); |
353 | status = 1; | 339 | lua_closestring(); |
354 | errorJmp = oldErr; | ||
355 | return status; | 340 | return status; |
356 | } | 341 | } |
357 | 342 | ||
343 | |||
358 | /* | 344 | /* |
359 | ** Get a parameter, returning the object handle or NULL on error. | 345 | ** Get a parameter, returning the object handle or NULL on error. |
360 | ** 'number' must be 1 to get the first parameter. | 346 | ** 'number' must be 1 to get the first parameter. |
@@ -426,42 +412,6 @@ void *lua_gettable (Object *object) | |||
426 | } | 412 | } |
427 | 413 | ||
428 | /* | 414 | /* |
429 | ** Given an object handle and a field name, return its field object. | ||
430 | ** On error, return NULL. | ||
431 | */ | ||
432 | Object *lua_getfield (Object *object, char *field) | ||
433 | { | ||
434 | if (object == NULL) return NULL; | ||
435 | if (tag(object) != LUA_T_ARRAY) | ||
436 | return NULL; | ||
437 | else | ||
438 | { | ||
439 | Object ref; | ||
440 | tag(&ref) = LUA_T_STRING; | ||
441 | svalue(&ref) = lua_constant[lua_findconstant(field)]; | ||
442 | return (lua_hashget(avalue(object), &ref)); | ||
443 | } | ||
444 | } | ||
445 | |||
446 | /* | ||
447 | ** Given an object handle and an index, return its indexed object. | ||
448 | ** On error, return NULL. | ||
449 | */ | ||
450 | Object *lua_getindexed (Object *object, float index) | ||
451 | { | ||
452 | if (object == NULL) return NULL; | ||
453 | if (tag(object) != LUA_T_ARRAY) | ||
454 | return NULL; | ||
455 | else | ||
456 | { | ||
457 | Object ref; | ||
458 | tag(&ref) = LUA_T_NUMBER; | ||
459 | nvalue(&ref) = index; | ||
460 | return (lua_hashget(avalue(object), &ref)); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | ** Get a global object. Return the object handle or NULL on error. | 415 | ** Get a global object. Return the object handle or NULL on error. |
466 | */ | 416 | */ |
467 | Object *lua_getglobal (char *name) | 417 | Object *lua_getglobal (char *name) |
@@ -550,7 +500,7 @@ int lua_storeglobal (char *name) | |||
550 | { | 500 | { |
551 | int n = lua_findsymbol (name); | 501 | int n = lua_findsymbol (name); |
552 | if (n < 0) return 1; | 502 | if (n < 0) return 1; |
553 | if (tag(top-1) == LUA_T_MARK) return 1; | 503 | if (top-stack <= CBase) return 1; |
554 | s_object(n) = *(--top); | 504 | s_object(n) = *(--top); |
555 | return 0; | 505 | return 0; |
556 | } | 506 | } |
@@ -598,74 +548,15 @@ int lua_storeindexed (lua_Object object, float index) | |||
598 | } | 548 | } |
599 | 549 | ||
600 | 550 | ||
601 | /* | 551 | int lua_type (lua_Object o) |
602 | ** Given an object handle, return if it is nil. | ||
603 | */ | ||
604 | int lua_isnil (Object *object) | ||
605 | { | 552 | { |
606 | return (object != NULL && tag(object) == LUA_T_NIL); | 553 | if (o == NULL) |
607 | } | 554 | return LUA_T_NIL; |
608 | 555 | else | |
609 | /* | 556 | return tag(o); |
610 | ** Given an object handle, return if it is a number one. | ||
611 | */ | ||
612 | int lua_isnumber (Object *object) | ||
613 | { | ||
614 | return (object != NULL && tag(object) == LUA_T_NUMBER); | ||
615 | } | ||
616 | |||
617 | /* | ||
618 | ** Given an object handle, return if it is a string one. | ||
619 | */ | ||
620 | int lua_isstring (Object *object) | ||
621 | { | ||
622 | return (object != NULL && tag(object) == LUA_T_STRING); | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | ** Given an object handle, return if it is an array one. | ||
627 | */ | ||
628 | int lua_istable (Object *object) | ||
629 | { | ||
630 | return (object != NULL && tag(object) == LUA_T_ARRAY); | ||
631 | } | ||
632 | |||
633 | /* | ||
634 | ** Given an object handle, return if it is a lua function. | ||
635 | */ | ||
636 | int lua_isfunction (Object *object) | ||
637 | { | ||
638 | return (object != NULL && tag(object) == LUA_T_FUNCTION); | ||
639 | } | ||
640 | |||
641 | /* | ||
642 | ** Given an object handle, return if it is a cfunction one. | ||
643 | */ | ||
644 | int lua_iscfunction (Object *object) | ||
645 | { | ||
646 | return (object != NULL && tag(object) == LUA_T_CFUNCTION); | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | ** Given an object handle, return if it is an user data one. | ||
651 | */ | ||
652 | int lua_isuserdata (Object *object) | ||
653 | { | ||
654 | return (object != NULL && tag(object) == LUA_T_USERDATA); | ||
655 | } | ||
656 | |||
657 | |||
658 | /* | ||
659 | ** Internal function: convert an object to a number | ||
660 | */ | ||
661 | void lua_obj2number (void) | ||
662 | { | ||
663 | Object *o = lua_getparam(1); | ||
664 | lua_pushobject (lua_convtonumber(o)); | ||
665 | } | 557 | } |
666 | 558 | ||
667 | 559 | ||
668 | |||
669 | /* | 560 | /* |
670 | ** Execute the given opcode, until a RET. Parameters are between | 561 | ** Execute the given opcode, until a RET. Parameters are between |
671 | ** [stack+base,top). Returns n such that the the results are between | 562 | ** [stack+base,top). Returns n such that the the results are between |
@@ -674,8 +565,7 @@ void lua_obj2number (void) | |||
674 | static int lua_execute (Byte *pc, int base) | 565 | static int lua_execute (Byte *pc, int base) |
675 | { | 566 | { |
676 | lua_debugline = 0; /* reset debug flag */ | 567 | lua_debugline = 0; /* reset debug flag */ |
677 | if (stack == NULL) | 568 | lua_checkstack(STACKGAP+MAX_TEMPS+base); |
678 | lua_initstack(); | ||
679 | while (1) | 569 | while (1) |
680 | { | 570 | { |
681 | OpCode opcode; | 571 | OpCode opcode; |
@@ -737,16 +627,13 @@ static int lua_execute (Byte *pc, int base) | |||
737 | break; | 627 | break; |
738 | 628 | ||
739 | case PUSHINDEXED: | 629 | case PUSHINDEXED: |
740 | { | 630 | pushsubscript(); |
741 | int s = lua_pushsubscript(); | 631 | break; |
742 | if (s == 1) return 1; | ||
743 | } | ||
744 | break; | ||
745 | 632 | ||
746 | case PUSHSELF: | 633 | case PUSHSELF: |
747 | { | 634 | { |
748 | Object receiver = *(top-2); | 635 | Object receiver = *(top-2); |
749 | if (lua_pushsubscript() == 1) return 1; | 636 | pushsubscript(); |
750 | *(top++) = receiver; | 637 | *(top++) = receiver; |
751 | break; | 638 | break; |
752 | } | 639 | } |
@@ -779,10 +666,7 @@ static int lua_execute (Byte *pc, int base) | |||
779 | { | 666 | { |
780 | int n = *pc++; | 667 | int n = *pc++; |
781 | if (tag(top-3-n) != LUA_T_ARRAY) | 668 | if (tag(top-3-n) != LUA_T_ARRAY) |
782 | { | 669 | lua_reportbug ("indexed expression not a table"); |
783 | lua_reportbug ("indexed expression not a table"); | ||
784 | return 1; | ||
785 | } | ||
786 | { | 670 | { |
787 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | 671 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); |
788 | if (h == NULL) return 1; | 672 | if (h == NULL) return 1; |
@@ -802,10 +686,7 @@ static int lua_execute (Byte *pc, int base) | |||
802 | n = *(pc++); | 686 | n = *(pc++); |
803 | arr = top-n-1; | 687 | arr = top-n-1; |
804 | if (tag(arr) != LUA_T_ARRAY) | 688 | if (tag(arr) != LUA_T_ARRAY) |
805 | { | 689 | lua_reportbug ("internal error - table expected"); |
806 | lua_reportbug ("internal error - table expected"); | ||
807 | return 1; | ||
808 | } | ||
809 | while (n) | 690 | while (n) |
810 | { | 691 | { |
811 | tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; | 692 | tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; |
@@ -821,10 +702,7 @@ static int lua_execute (Byte *pc, int base) | |||
821 | int n = *(pc++); | 702 | int n = *(pc++); |
822 | Object *arr = top-n-1; | 703 | Object *arr = top-n-1; |
823 | if (tag(arr) != LUA_T_ARRAY) | 704 | if (tag(arr) != LUA_T_ARRAY) |
824 | { | 705 | lua_reportbug ("internal error - table expected"); |
825 | lua_reportbug ("internal error - table expected"); | ||
826 | return 1; | ||
827 | } | ||
828 | while (n) | 706 | while (n) |
829 | { | 707 | { |
830 | CodeWord code; | 708 | CodeWord code; |
@@ -851,8 +729,6 @@ static int lua_execute (Byte *pc, int base) | |||
851 | get_word(size,pc); | 729 | get_word(size,pc); |
852 | top++; | 730 | top++; |
853 | avalue(top-1) = lua_createarray(size.w); | 731 | avalue(top-1) = lua_createarray(size.w); |
854 | if (avalue(top-1) == NULL) | ||
855 | return 1; | ||
856 | tag(top-1) = LUA_T_ARRAY; | 732 | tag(top-1) = LUA_T_ARRAY; |
857 | } | 733 | } |
858 | break; | 734 | break; |
@@ -870,7 +746,7 @@ static int lua_execute (Byte *pc, int base) | |||
870 | switch (tag(l)) | 746 | switch (tag(l)) |
871 | { | 747 | { |
872 | case LUA_T_NIL: | 748 | case LUA_T_NIL: |
873 | res = 0; break; | 749 | res = 1; break; |
874 | case LUA_T_NUMBER: | 750 | case LUA_T_NUMBER: |
875 | res = (nvalue(l) == nvalue(r)); break; | 751 | res = (nvalue(l) == nvalue(r)); break; |
876 | case LUA_T_ARRAY: | 752 | case LUA_T_ARRAY: |