summaryrefslogtreecommitdiff
path: root/src/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lcode.c')
-rw-r--r--src/lcode.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/src/lcode.c b/src/lcode.c
index 72afce96..cfe4a210 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1,16 +1,18 @@
/*
-** $Id: lcode.c,v 2.90 2014/05/08 18:58:46 roberto Exp $
+** $Id: lcode.c,v 2.97 2014/11/24 14:59:22 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
+#define lcode_c
+#define LUA_CORE
+
+#include "lprefix.h"
+
#include <math.h>
#include <stdlib.h>
-#define lcode_c
-#define LUA_CORE
-
#include "lua.h"
#include "lcode.h"
@@ -27,7 +29,11 @@
#include "lvm.h"
-/* test for x == -0 */
+/* Maximum number of registers in a Lua function */
+#define MAXREGS 250
+
+
+/* test for x == -0 ('signbit' needs 'math.h') */
#if defined(signbit)
#define isminuszero(x) ((x) == 0.0 && signbit(x))
#else
@@ -107,7 +113,7 @@ static void fixjump (FuncState *fs, int pc, int dest) {
/*
-** returns current `pc' and marks it as a jump target (to avoid wrong
+** returns current 'pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block).
*/
int luaK_getlabel (FuncState *fs) {
@@ -230,7 +236,7 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
static int luaK_code (FuncState *fs, Instruction i) {
Proto *f = fs->f;
- dischargejpc(fs); /* `pc' will change */
+ dischargejpc(fs); /* 'pc' will change */
/* put new instruction in code array */
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
MAX_INT, "opcodes");
@@ -280,7 +286,7 @@ int luaK_codek (FuncState *fs, int reg, int k) {
void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) {
- if (newstack >= MAXSTACK)
+ if (newstack >= MAXREGS)
luaX_syntaxerror(fs->ls, "function or expression too complex");
fs->f->maxstacksize = cast_byte(newstack);
}
@@ -503,7 +509,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) {
static void exp2reg (FuncState *fs, expdesc *e, int reg) {
discharge2reg(fs, e, reg);
if (e->k == VJMP)
- luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */
+ luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */
if (hasjumps(e)) {
int final; /* position after whole expression */
int p_f = NO_JUMP; /* position of an eventual LOAD false */
@@ -585,7 +591,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
}
case VK: {
vk:
- if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
+ if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
return RKASK(e->u.info);
else break;
}
@@ -677,7 +683,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
break;
}
}
- luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
+ luaK_concat(fs, &e->f, pc); /* insert last jump in 'f' list */
luaK_patchtohere(fs, e->t);
e->t = NO_JUMP;
}
@@ -700,7 +706,7 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) {
break;
}
}
- luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
+ luaK_concat(fs, &e->t, pc); /* insert last jump in 't' list */
luaK_patchtohere(fs, e->f);
e->f = NO_JUMP;
}
@@ -762,12 +768,10 @@ static int validop (int op, TValue *v1, TValue *v2) {
(cast_void(tonumber(v2, &b)), b)))
return 0;
switch (op) {
- case LUA_OPIDIV: /* division by 0 and conversion errors */
- return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0);
case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: /* conversion errors */
return (tointeger(v1, &i) && tointeger(v2, &i));
- case LUA_OPMOD: /* integer module by 0 */
+ case LUA_OPIDIV: case LUA_OPMOD: /* integer division by 0 */
return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0);
default: return 1; /* everything else is valid */
}
@@ -797,19 +801,30 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
}
-static void codearith (FuncState *fs, OpCode op,
- expdesc *e1, expdesc *e2, int line) {
- if (!constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) {
+/*
+** Code for binary and unary expressions that "produce values"
+** (arithmetic operations, bitwise operations, concat, length). First
+** try to do constant folding (only for numeric [arithmetic and
+** bitwise] operations, which is what 'lua_arith' accepts).
+** Expression to produce final result will be encoded in 'e1'.
+*/
+static void codeexpval (FuncState *fs, OpCode op,
+ expdesc *e1, expdesc *e2, int line) {
+ lua_assert(op >= OP_ADD);
+ if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2))
+ return; /* result has been folded */
+ else {
int o1, o2;
- if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) {
- o2 = 0;
+ /* move operands to registers (if needed) */
+ if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */
+ o2 = 0; /* no second expression */
o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
}
else { /* regular case (binary operators) */
- o2 = luaK_exp2RK(fs, e2);
+ o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
o1 = luaK_exp2RK(fs, e1);
}
- if (o1 > o2) {
+ if (o1 > o2) { /* free registers in proper order */
freeexp(fs, e1);
freeexp(fs, e2);
}
@@ -817,8 +832,8 @@ static void codearith (FuncState *fs, OpCode op,
freeexp(fs, e2);
freeexp(fs, e1);
}
- e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
- e1->k = VRELOCABLE;
+ e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */
+ e1->k = VRELOCABLE; /* all those operations are relocable */
luaK_fixline(fs, line);
}
}
@@ -831,7 +846,7 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
freeexp(fs, e2);
freeexp(fs, e1);
if (cond == 0 && op != OP_EQ) {
- int temp; /* exchange args to replace by `<' or `<=' */
+ int temp; /* exchange args to replace by '<' or '<=' */
temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
cond = 1;
}
@@ -845,7 +860,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
switch (op) {
case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
- codearith(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
+ codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
break;
}
case OPR_NOT: codenot(fs, e); break;
@@ -865,7 +880,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
break;
}
case OPR_CONCAT: {
- luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
+ luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */
break;
}
case OPR_ADD: case OPR_SUB:
@@ -911,7 +926,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
}
else {
luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
- codearith(fs, OP_CONCAT, e1, e2, line);
+ codeexpval(fs, OP_CONCAT, e1, e2, line);
}
break;
}
@@ -919,7 +934,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
case OPR_IDIV: case OPR_MOD: case OPR_POW:
case OPR_BAND: case OPR_BOR: case OPR_BXOR:
case OPR_SHL: case OPR_SHR: {
- codearith(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
+ codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
break;
}
case OPR_EQ: case OPR_LT: case OPR_LE: {