]> git.lizzy.rs Git - metalua.git/blob - junk/combine.c
Merge remote branch 'origin/master'
[metalua.git] / junk / combine.c
1 /* This should combine several functions into one, when they're already
2  * compiled into functions. Useful when we don't have their AST, e.g.
3  * to link several precompiled chunks into one.
4  *
5  * It currently doesn't work; meanwhile, one can use the original
6  * 'luac' executable, although it doesn't handle argument passing through
7  * "..." correctly.
8  */
9
10 #include <lua.h>
11 #include <lapi.h>
12 #include <lfunc.h>
13 #include <lstate.h>
14 #include <lstring.h>
15 #include <lopcodes.h>
16 #include <ldo.h>
17
18 static int lua_combine( lua_State* L) {
19   int n = lua_gettop( L); /* Number of functions to combine */
20   if( 1 == n) {
21     return 1; /* Only one function, nothing to combine */
22   } else {
23       int i, pc = 3*n + 1;
24       Proto* f = luaF_newproto( L);
25       setptvalue2s( L,L->top,f); 
26       incr_top( L);
27       f->source       = luaS_newliteral( L,"=(combiner)");
28       f->maxstacksize = 2;
29       f->is_vararg    = VARARG_ISVARARG;
30       f->code         = luaM_newvector(L, pc, Instruction);
31       f->sizecode     = pc;
32       f->p            = luaM_newvector( L, n, Proto*);
33       f->sizep        = n;
34       for( i = pc = 0; i < n; i ++) {
35         int proto_idx = i-n-1;
36         Proto *p      = clvalue( L->top + proto_idx)->l.p;
37         f->p[i]       = p;
38         f->code[pc++] = CREATE_ABx( OP_CLOSURE, 0, i);
39         f->code[pc++] = CREATE_ABx( OP_VARARG,  1, 0);
40         f->code[pc++] = CREATE_ABC( OP_CALL,    0, 0, 1);
41       }
42       f->code[pc++]   = CREATE_ABC( OP_RETURN, 0, 1, 0);
43       return 1;
44     }
45 }
46
47 int luaopen_combine( lua_State *L) {
48   lua_pushcfunction( L, lua_combine);
49   lua_setglobal( L, "combine");
50   return 0;
51 }