add type info to upvalues and enable new opcodes SETUPVALI etc.

pull/81/head
Dibyendu Majumdar 9 years ago
parent 98d74905e4
commit 15761f3cf0

@ -370,16 +370,6 @@ typedef union UUdata {
io->value_ = iu->user_; io->tt_ = iu->ttuv_; \
checkliveness(G(L),io); }
/*
** Description of an upvalue for function prototypes
*/
typedef struct Upvaldesc {
TString *name; /* upvalue name (for debug information) */
lu_byte instack; /* whether it is in stack */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc;
/* Following are the types we will use
** use in parsing. The rationale for types is
** performance - as of now these are the only types that
@ -399,6 +389,17 @@ typedef enum {
RAVI_TBOOLEAN
} ravitype_t;
/*
** Description of an upvalue for function prototypes
*/
typedef struct Upvaldesc {
TString *name; /* upvalue name (for debug information) */
ravitype_t type; /* RAVI type of upvalue */
lu_byte instack; /* whether it is in stack */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc;
/*
** Description of a local variable for function prototypes
** (used for debug information)

@ -283,10 +283,15 @@ OP_RAVI_FORLOOP_I1,
OP_RAVI_FORPREP_IP,
OP_RAVI_FORPREP_I1,
OP_RAVI_SETUPVALI, /* A B UpValue[B] := tointeger(R(A)) */
OP_RAVI_SETUPVALF, /* A B UpValue[B] := tonumber(R(A)) */
OP_RAVI_SETUPVALAI, /* A B UpValue[B] := toarrayint(R(A)) */
OP_RAVI_SETUPVALAF, /* A B UpValue[B] := toarrayflt(R(A)) */
} OpCode;
#define NUM_OPCODES (cast(int, OP_RAVI_FORPREP_I1) + 1)
#define NUM_OPCODES (cast(int, OP_RAVI_SETUPVALAF) + 1)
/*===========================================================================
Notes:

@ -64,9 +64,9 @@ end
assert(a[4] == nil)
a[1].set(10)
assert(a[2].get() == 2)
a[2].set('a')
--a[2].set('a')
assert(a[3].get() == 3)
assert(a[2].get() == 'a')
--assert(a[2].get() == 'a')
a = {}
local t = {"a", "b"}

@ -718,6 +718,27 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
#endif
}
static OpCode check_valid_setupval(FuncState *fs, expdesc *var, expdesc *ex) {
OpCode op = OP_SETUPVAL;
if (var->ravi_type != RAVI_TANY && var->ravi_type != ex->ravi_type) {
if (var->ravi_type == RAVI_TNUMINT)
op = OP_RAVI_SETUPVALI;
else if (var->ravi_type == RAVI_TNUMFLT)
op = OP_RAVI_SETUPVALF;
else if (var->ravi_type == RAVI_TARRAYINT)
op = OP_RAVI_SETUPVALAI;
else if (var->ravi_type == RAVI_TARRAYFLT)
op = OP_RAVI_SETUPVALAF;
else
luaX_syntaxerror(fs->ls,
luaO_pushfstring(fs->ls->L, "Invalid assignment of "
"upvalue: upvalue type "
"%d, expression type %d",
var->ravi_type, ex->ravi_type));
}
return op;
}
/* Emit store for LHS expression. */
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
switch (var->k) {
@ -728,8 +749,9 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
return;
}
case VUPVAL: {
OpCode op = check_valid_setupval(fs, var, ex);
int e = luaK_exp2anyreg(fs, ex);
luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
luaK_codeABC(fs, op, e, var->u.info, 0);
break;
}
case VINDEXED: {

@ -125,6 +125,11 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"FORPREP_IP",
"FORPREP_I1",
"SETUPVALI",
"SETUPVALF",
"SETUPVALAI",
"SETUPVALAF",
NULL
};
@ -236,6 +241,10 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
, opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_RAVI_FORLOOP_I1 */
, opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_RAVI_FORPREP_IP */
, opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_RAVI_FORPREP_I1 */
, opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RAVI_SETUPVALI */
, opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RAVI_SETUPVALF */
, opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RAVI_SETUPVALAI */
, opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RAVI_SETUPVALAF */
};
@ -431,6 +440,10 @@ static void PrintCode(const Proto* f)
printf("\t; "); PrintConstant(f, bx);
break;
case OP_GETUPVAL:
case OP_RAVI_SETUPVALI:
case OP_RAVI_SETUPVALF:
case OP_RAVI_SETUPVALAI:
case OP_RAVI_SETUPVALAF:
case OP_SETUPVAL:
printf("\t; %s", UPVALNAME(b));
break;

@ -457,9 +457,12 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
Upvaldesc, MAXUPVAL, "upvalues");
while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
f->upvalues[fs->nups].name = name;
//raviY_printf(fs, "Creating upvalue for local variable exp %e\n", v);
f->upvalues[fs->nups].type = v->ravi_type;
luaC_objbarrier(fs->ls->L, f, name);
return fs->nups++;
}
@ -514,7 +517,7 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
/* else was LOCAL or UPVAL */
idx = newupvalue(fs, n, var); /* will be a new upvalue */
}
init_exp(var, VUPVAL, idx, RAVI_TANY); /* RAVI : variable type not known as global or upvalue */
init_exp(var, VUPVAL, idx, fs->f->upvalues[idx].type); /* RAVI : set upvalue type */
return VUPVAL;
}
}

@ -1463,6 +1463,42 @@ newframe: /* reentry point when frame changes (call/return) */
raviH_set_float_inline(L, t, idx, ((lua_Number)ivalue(rc)));
}
} break;
case OP_RAVI_SETUPVALI: {
lua_Integer ia;
if (tointeger(ra, &ia)) {
UpVal *uv = cl->upvals[GETARG_B(i)];
setivalue(uv->v, ia);
luaC_upvalbarrier(L, uv);
}
else
luaG_runerror(L, "upvalue of integer type, cannot be set to non integer value");
} break;
case OP_RAVI_SETUPVALF: {
lua_Number na;
if (tonumber(ra, &na)) {
UpVal *uv = cl->upvals[GETARG_B(i)];
setfltvalue(uv->v, na);
luaC_upvalbarrier(L, uv);
}
else
luaG_runerror(L, "upvalue of number type, cannot be set to non number value");
} break;
case OP_RAVI_SETUPVALAI: {
if (!ttistable(ra) || hvalue(ra)->ravi_array.type != RAVI_TARRAYINT)
luaG_runerror(L, "upvalue of integer[] type, cannot be set to non integer[] value");
UpVal *uv = cl->upvals[GETARG_B(i)];
setobj(L, uv->v, ra);
luaC_upvalbarrier(L, uv);
} break;
case OP_RAVI_SETUPVALAF: {
if (!ttistable(ra) || hvalue(ra)->ravi_array.type != RAVI_TARRAYFLT)
luaG_runerror(L, "upvalue of number[] type, cannot be set to non number[] value");
UpVal *uv = cl->upvals[GETARG_B(i)];
setobj(L, uv->v, ra);
luaC_upvalbarrier(L, uv);
} break;
}
}
}

@ -74,6 +74,8 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
InstructionT = C_intT;
pInstructionT = llvm::PointerType::get(InstructionT, 0);
ravitype_tT = llvm::Type::getIntNTy(context, sizeof(ravitype_t) * 8);
lua_StateT = llvm::StructType::create(context, "ravi.lua_State");
plua_StateT = llvm::PointerType::get(lua_StateT, 0);
@ -227,15 +229,17 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
//*/
// typedef struct Upvaldesc {
// TString *name; /* upvalue name (for debug information) */
// ravitype_t type;
// lu_byte instack; /* whether it is in stack */
// lu_byte idx; /* index of upvalue (in stack or in outer function's list)
// */
//}Upvaldesc;
UpvaldescT = llvm::StructType::create(context, "ravi.Upvaldesc");
elements.clear();
elements.push_back(pTStringT);
elements.push_back(lu_byteT);
elements.push_back(lu_byteT);
elements.push_back(pTStringT); /* name */
elements.push_back(ravitype_tT); /* type */
elements.push_back(lu_byteT); /* instack */
elements.push_back(lu_byteT); /* idx */
UpvaldescT->setBody(elements);
pUpvaldescT = llvm::PointerType::get(UpvaldescT, 0);
@ -250,7 +254,6 @@ LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) {
// ravitype_t ravi_type; /* RAVI type of the variable - RAVI_TANY if unknown
// */
//} LocVar;
ravitype_tT = llvm::Type::getIntNTy(context, sizeof(ravitype_t) * 8);
LocVarT = llvm::StructType::create(context, "ravi.LocVar");
elements.clear();
elements.push_back(pTStringT); /* varname */

@ -122,6 +122,7 @@ int main(int argc, const char *argv[])
{
int failures = 0;
//
failures += test_luacompexec1("function test(); local x: integer = 1; return function (j) x = j; return x; end; end; fn = test(); return fn('55')", 55);
failures += test_luacompexec1("ravi.auto(true); function arrayaccess (); local x: integer[] = {5}; return x[1]; end; assert(ravi.compile(arrayaccess)); return arrayaccess()", 5);
failures += test_luacompexec1("ravi.auto(true); function cannotload (msg, a,b); assert(not a and string.find(b, msg)); end; ravi.compile(cannotload); return 1", 1);
failures += test_luacompexec1("ravi.auto(true); function z(); local a = 5; a = a + 1; return a; end; ravi.compile(z); return z()", 6);

Loading…
Cancel
Save