Esempio n. 1
0
static void constructor (LexState *ls, expdesc *t) {
  /* constructor -> ?? */
  int force_size_na = 0;
  int force_size_nh = 0;
  FuncState *fs = ls->fs;
  int line = ls->linenumber;
  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
  struct ConsControl cc;
  cc.na = cc.nh = cc.tostore = 0;
  cc.t = t;
  init_exp(t, VRELOCABLE, pc);
  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top (for gc) */
  check(ls, '{');
  if (testnext(ls, '&')) {
    if (ls->t.token != TK_NUMBER)
      luaX_syntaxerror(ls, luaO_pushfstring(ls->L, "size expected following & (line %d)", ls->linenumber));
    force_size_nh = (int)ls->t.seminfo.r;
	next(ls);
    if (testnext(ls, '&')) {
      if (ls->t.token != TK_NUMBER)
        luaX_syntaxerror(ls, luaO_pushfstring(ls->L, "size expected following & (line %d)", ls->linenumber));
      force_size_na = (int)ls->t.seminfo.r;
      next(ls);
	}
  }
  do {
    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
    testnext(ls, ';');  /* compatibility only */
    if (ls->t.token == '}') break;
    closelistfield(fs, &cc);
    switch(ls->t.token) {
      case TK_NAME: {  /* may be listfields or recfields */
        lookahead(ls);
        if (ls->lookahead.token != '=')  /* expression? */
          listfield(ls, &cc);
        else
          recfield(ls, &cc);
        break;
      }
      case '[': {  /* constructor_item -> recfield */
        recfield(ls, &cc);
        break;
      }
      default: {  /* constructor_part -> listfield */
        listfield(ls, &cc);
        break;
      }
    }
  } while (testnext(ls, ',') || testnext(ls, ';'));
  check_match(ls, '}', '{', line);
  lastlistfield(fs, &cc);
  if (force_size_na > cc.na)
	cc.na = force_size_na;
  if (force_size_nh > cc.nh)
    cc.nh = force_size_nh;
  if (cc.na > 0)
  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
  SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1);  /* set initial table size */
}
Esempio n. 2
0
static void constructor(LexState* ls, expdesc* t)
{
	/* constructor -> ?? */
	FuncState* fs = ls->fs;
	int line = ls->linenumber;
	int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
	struct ConsControl cc;
	cc.na = cc.nh = cc.tostore = 0;
	cc.t = t;
	init_exp(t, VRELOCABLE, pc);
	init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
	luaK_exp2nextreg(ls->fs, t);	/* fix it at stack top (for gc) */
	checknext(ls, '{');
	do
	{
		lua_assert(cc.v.k == VVOID || cc.tostore > 0);
		if (ls->t.token == '}') break;
		closelistfield(fs, &cc);
		switch (ls->t.token)
		{
			case TK_NAME:	 /* may be listfields or recfields */
			{
				luaX_lookahead(ls);
				if (ls->lookahead.token != '=')	 /* expression? */
					listfield(ls, &cc);
				else
					recfield(ls, &cc);
				break;
			}
			case '[':    /* constructor_item -> recfield */
			{
				recfield(ls, &cc);
				break;
			}
			default:    /* constructor_part -> listfield */
			{
				listfield(ls, &cc);
				break;
			}
		}
	}
	while (testnext(ls, ',') || testnext(ls, ';'));
	check_match(ls, '}', '{', line);
	lastlistfield(fs, &cc);
	SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
	SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));	/* set initial table size */
}
Esempio n. 3
0
static void constructor (LexState *ls, expdesc *t) {
  /* constructor -> ?? */
  FuncState *fs = ls->fs;
  int line = ls->linenumber;
  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
  struct ConsControl cc;
  cc.na = cc.nh = cc.tostore = 0;
  cc.t = t;
  init_exp(t, VRELOCABLE, pc);
  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top (for gc) */
  checknext(ls, '{');
#if LUA_OPTIONAL_COMMA
  for (;;) {
#else
  do {
#endif /* LUA_OPTIONAL_COMMA */
    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
    if (ls->t.token == '}') break;
    closelistfield(fs, &cc);
    switch(ls->t.token) {
      case TK_NAME: {  /* may be listfields or recfields */
        luaX_lookahead(ls);
        if (ls->lookahead.token != '=')  /* expression? */
          listfield(ls, &cc);
        else
          recfield(ls, &cc);
        break;
      }
      case '[': {  /* constructor_item -> recfield */
        recfield(ls, &cc);
        break;
      }
      default: {  /* constructor_part -> listfield */
        listfield(ls, &cc);
        break;
      }
    }
#if LUA_OPTIONAL_COMMA
	if (ls->t.token == ',' || ls->t.token == ';')
		next(ls);
	else if (ls->t.token == '}')
		break;
  }
#else
  } while (testnext(ls, ',') || testnext(ls, ';'));
#endif /* LUA_OPTIONAL_COMMA */
  check_match(ls, '}', '{', line);
  lastlistfield(fs, &cc);
  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
  SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));  /* set initial table size */
}

/* }====================================================================== */



static void parlist (LexState *ls) {
  /* parlist -> [ param { `,' param } ] */
  FuncState *fs = ls->fs;
  Proto *f = fs->f;
  int nparams = 0;
  f->is_vararg = 0;
  if (ls->t.token != ')') {  /* is `parlist' not empty? */
    do {
      switch (ls->t.token) {
        case TK_NAME: {  /* param -> NAME */
          new_localvar(ls, str_checkname(ls), nparams++);
          break;
        }
        case TK_DOTS: {  /* param -> `...' */
          luaX_next(ls);
#if defined(LUA_COMPAT_VARARG)
          /* use `arg' as default name */
          new_localvarliteral(ls, "arg", nparams++);
          f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
#endif
          f->is_vararg |= VARARG_ISVARARG;
          break;
        }
        default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
      }
    } while (!f->is_vararg && testnext(ls, ','));
  }
  adjustlocalvars(ls, nparams);
  f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
  luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
}
Esempio n. 4
0
/*
 * If the luac command line includes multiple files or has the -f option 
 * then luac generates a main function to reference all sub-main prototypes.
 * This is one of two types:
 *   Type 0   The standard luac combination main
 *   Type 1   A lookup wrapper that facilitates indexing into the generated protos 
 */
static const Proto* combine(lua_State* L, int n, int type)
{
 if (n==1 && type == 0)
  return toproto(L,-1);
 else
 {
  int i;
  Instruction *pc;
  Proto* f=luaF_newproto(L);
  setptvalue2s(L,L->top,f); incr_top(L);
  f->source=luaS_newliteral(L,"=(" PROGNAME ")");
  f->p=luaM_newvector(L,n,Proto*);
  f->sizep=n;
  for (i=0; i<n; i++) 
    f->p[i]=toproto(L,i-n-1);
  pc=0;

  if (type == 0) {
  /*
   * Type 0 is as per the standard luac, which is just a main routine which 
   * invokes all of the compiled functions sequentially.  This is fine if 
   * they are self registering modules, but useless otherwise.
   */
   f->numparams    = 0;
   f->maxstacksize = 1;
   f->sizecode     = 2*n + 1 ;
   f->sizek        = 0;
   f->code         = luaM_newvector(L, f->sizecode , Instruction);
   f->k            = luaM_newvector(L,f->sizek,TValue);

   for (i=0, pc = f->code; i<n; i++) {
    *pc++ = CREATE_ABx(OP_CLOSURE,0,i);
    *pc++ = CREATE_ABC(OP_CALL,0,1,1);
   }
   *pc++ = CREATE_ABC(OP_RETURN,0,1,0);
  } else {
  /*
   * The Type 1 main() is a lookup which takes a single argument, the name to  
   * be resolved. If this matches root name of one of the compiled files then
   * a closure to this file main is returned.  Otherwise the Unixtime of the
   * compile and the list of root names is returned.
   */
   if (n > LFIELDS_PER_FLUSH) {
#define NO_MOD_ERR_(n) ": Number of modules > " #n
#define NO_MOD_ERR(n) NO_MOD_ERR_(n)
    usage(LUA_QL("-f")  NO_MOD_ERR(LFIELDS_PER_FLUSH));
   }
   f->numparams    = 1;
   f->maxstacksize = n + 3;
   f->sizecode     = 5*n + 5 ;
   f->sizek        = n + 1;
   f->sizelocvars  = 0;
   f->code         = luaM_newvector(L, f->sizecode , Instruction);
   f->k            = luaM_newvector(L,f->sizek,TValue);
   for (i=0, pc = f->code; i<n; i++)  
   {
    /* if arg1 == FnameA then return function (...) -- funcA -- end end */
    setsvalue2n(L,f->k+i,corename(L, f->p[i]->source));
    *pc++ = CREATE_ABC(OP_EQ,0,0,RKASK(i)); 
    *pc++ = CREATE_ABx(OP_JMP,0,MAXARG_sBx+2);
    *pc++ = CREATE_ABx(OP_CLOSURE,1,i);
    *pc++ = CREATE_ABC(OP_RETURN,1,2,0);
   }

   setnvalue(f->k+n, (lua_Number) time(NULL));

   *pc++ = CREATE_ABx(OP_LOADK,1,n);
   *pc++ = CREATE_ABC(OP_NEWTABLE,2,luaO_int2fb(i),0);   
   for (i=0; i<n; i++) 
     *pc++ = CREATE_ABx(OP_LOADK,i+3,i);
   *pc++ = CREATE_ABC(OP_SETLIST,2,i,1);   
   *pc++ = CREATE_ABC(OP_RETURN,1,3,0);
   *pc++ = CREATE_ABC(OP_RETURN,0,1,0);
  }
  lua_assert((pc-f->code) == f->sizecode);

  return f;
 }
}