better way to cope with opcode variants

This commit is contained in:
Roberto Ierusalimschy
1997-09-22 17:53:20 -03:00
parent 2079cfe8fa
commit d6c867ea50
3 changed files with 162 additions and 179 deletions

180
lua.stx
View File

@@ -1,6 +1,6 @@
%{
/*
** $Id: lua.stx,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $
** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $
** Syntax analizer and code generator
** See Copyright Notice in lua.h
*/
@@ -94,6 +94,22 @@ static void code_byte (Byte c)
}
static void code_word_at (int pc, int n)
{
Word w = n;
if (w != n)
luaY_error("block too big");
currState->f->code[pc] = n&0xFF;
currState->f->code[pc+1] = n>>8;
}
static void code_word (int n)
{
code_byte(n&0xFF);
code_byte(n>>8);
}
static void deltastack (int delta)
{
currState->stacksize += delta;
@@ -112,9 +128,25 @@ static void code_opcode (OpCode op, int delta)
}
static void code_push (OpCode op)
static void code_opborw(OpCode opbyte, int arg, int delta)
{
code_opcode(op, 1);
if (arg <= 255) {
code_opcode(opbyte, delta);
code_byte(arg);
}
else {
code_opcode(opbyte+1, delta);
code_word(arg);
}
}
static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta)
{
if (firstop+arg < opbyte)
code_opcode(firstop+arg, delta);
else
code_opborw(opbyte, arg, delta);
}
@@ -133,31 +165,9 @@ static void code_pop (OpCode op)
#define code_unop(op) code_neutralop(op)
static void code_word_at (int pc, int n)
{
Word w = n;
if (w != n)
luaY_error("block too big");
currState->f->code[pc] = n&0xFF;
currState->f->code[pc+1] = n>>8;
}
static void code_word (int n)
{
code_byte(n&0xFF);
code_byte(n>>8);
}
static void code_constant (int c)
{
if (c <= 255) {
code_push(PUSHCONSTANTB);
code_byte(c);
}
else {
code_push(PUSHCONSTANT);
code_word(c);
}
code_opborw(PUSHCONSTANTB, c, 1);
}
@@ -216,18 +226,8 @@ static int real_constant (real r)
static void code_number (real f)
{
Word i;
if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) {
/* f has an (short) integer value */
if (i <= 2) code_push(PUSH0 + i);
else if (i <= 255) {
code_push(PUSHBYTE);
code_byte(i);
}
else {
code_push(PUSHWORD);
code_word(i);
}
}
if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f)
code_oparg(PUSH0, PUSHBYTE, i, 1); /* f has an (short) integer value */
else
code_constant(real_constant(f));
}
@@ -344,12 +344,7 @@ static void pushupvalue (TaggedString *n)
if (aux_localname(n, currState) >= 0)
luaY_syntaxerror("cannot access an upvalue in current scope", n->str);
i = indexupvalue(n);
if (i == 0)
code_push(PUSHUPVALUE0);
else {
code_push(PUSHUPVALUE);
code_byte(i);
}
code_oparg(PUSHUPVALUE0, PUSHUPVALUE, i, 1);
}
@@ -366,18 +361,10 @@ void luaY_codedebugline (int line)
static void adjuststack (int n)
{
if (n > 0) {
code_opcode(POPS, -n);
code_byte(n);
}
else if (n < 0) {
if (n == -1)
code_push(PUSHNIL);
else {
code_opcode(PUSHNILS, -n);
code_byte(-n);
}
}
if (n > 0)
code_oparg(POP1-1, POPS, n, -n); /* POP1-1 = POP0 */
else if (n < 0)
code_oparg(PUSHNIL-1, PUSHNILS, -n, -n); /* PUSHNIL1-1 = PUSHNIL0 */
}
@@ -426,29 +413,12 @@ static void code_args (int dots)
static void lua_pushvar (vardesc number)
{
if (number > 0) { /* global var */
number--;
if (number <= 255) {
code_push(PUSHGLOBALB);
code_byte(number);
}
else {
code_push(PUSHGLOBAL);
code_word(number);
}
}
else if (number < 0) { /* local var */
number = (-number) - 1;
if (number < 10)
code_push(PUSHLOCAL0 + number);
else {
code_push(PUSHLOCAL);
code_byte(number);
}
}
else {
if (number > 0) /* global var */
code_opborw(GETGLOBALB, number-1, 1);
else if (number < 0) /* local var */
code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1);
else
code_pop(GETTABLE);
}
}
@@ -456,26 +426,10 @@ static void storevar (vardesc number)
{
if (number == 0) /* indexed var */
code_opcode(SETTABLE0, -3);
else if (number > 0) { /* global var */
number--;
if (number <= 255) {
code_pop(SETGLOBALB);
code_byte(number);
}
else {
code_pop(SETGLOBAL);
code_word(number);
}
}
else { /* number < 0 - local var */
number = (-number) - 1;
if (number < 10)
code_pop(SETLOCAL0 + number);
else {
code_pop(SETLOCAL);
code_byte(number);
}
}
else if (number > 0) /* global var */
code_opborw(SETGLOBALB, number-1, -1);
else /* number < 0 - local var */
code_oparg(SETLOCAL0, SETLOCAL, (-number)-1, -1);
}
@@ -535,8 +489,7 @@ static void func_onstack (TProtoFunc *f)
currState->f->consts[c].value.tf = (currState+1)->f;
for (i=0; i<nupvalues; i++)
lua_pushvar((currState+1)->upvalues[i]);
code_constant(c);
code_opcode(CLOSURE, -nupvalues);
code_opborw(CLOSUREB, c, 1-nupvalues);
}
@@ -771,7 +724,7 @@ expr : '(' expr ')' { $$ = $2; }
| varexp { $$ = 0;}
| NUMBER { code_number($1); $$ = 0; }
| STRING { code_string($1); $$ = 0; }
| NIL {code_push(PUSHNIL); $$ = 0; }
| NIL {code_opcode(PUSHNIL, 1); $$ = 0; }
| functioncall { $$ = $1; }
| expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
| expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; }
@@ -779,14 +732,9 @@ expr : '(' expr ')' { $$ = $2; }
;
table :
{
code_push(CREATEARRAY);
$<vInt>$ = currState->pc; code_word(0);
}
'{' fieldlist '}'
{
code_word_at($<vInt>1, $3);
}
{ code_opcode(CREATEARRAY, 1); $<vInt>$ = currState->pc; code_word(0); }
'{' fieldlist '}'
{ code_word_at($<vInt>1, $3); }
;
functioncall : funcvalue funcParams
@@ -801,8 +749,7 @@ functioncall : funcvalue funcParams
funcvalue : varexp { $$ = 0; }
| varexp ':' NAME
{
code_push(PUSHSELF);
code_word(string_constant($3, currState));
code_opborw(PUSHSELFB, string_constant($3, currState), 1);
$$ = 1;
}
;
@@ -909,15 +856,8 @@ varlist1 : var
;
var : singlevar { $$ = $1; }
| varexp '[' expr1 ']'
{
$$ = 0; /* indexed variable */
}
| varexp '.' NAME
{
code_string($3);
$$ = 0; /* indexed variable */
}
| varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */
| varexp '.' NAME { code_string($3); $$ = 0; }/* ind. var. */
;
singlevar : NAME { $$ = singlevar($1, currState); }