FFI: Parse complex and 64 bit integer literals.
This commit is contained in:
@@ -17,6 +17,9 @@
|
||||
#include "lj_func.h"
|
||||
#include "lj_state.h"
|
||||
#include "lj_bc.h"
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ctype.h"
|
||||
#endif
|
||||
#include "lj_lex.h"
|
||||
#include "lj_parse.h"
|
||||
#include "lj_vm.h"
|
||||
@@ -33,6 +36,7 @@ typedef enum {
|
||||
VKSTR, /* sval = string value */
|
||||
VKNUM, /* nval = number value */
|
||||
VKLAST = VKNUM,
|
||||
VKCDATA, /* nval = cdata value, not treated as a constant expression */
|
||||
/* Non-constant expressions follow: */
|
||||
VLOCAL, /* info = local register */
|
||||
VUPVAL, /* info = upvalue index */
|
||||
@@ -61,7 +65,7 @@ typedef struct ExpDesc {
|
||||
} ExpDesc;
|
||||
|
||||
/* Macros for expressions. */
|
||||
#define expr_hasjump(e) ((e)->t != (e)->f)
|
||||
#define expr_hasjump(e) ((e)->t != (e)->f)
|
||||
|
||||
#define expr_isk(e) ((e)->k <= VKLAST)
|
||||
#define expr_isk_nojump(e) (expr_isk(e) && !expr_hasjump(e))
|
||||
@@ -216,6 +220,17 @@ GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len)
|
||||
return s;
|
||||
}
|
||||
|
||||
#if LJ_HASFFI
|
||||
/* Anchor cdata to avoid GC. */
|
||||
void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd)
|
||||
{
|
||||
/* NOBARRIER: the key is new or kept alive. */
|
||||
lua_State *L = ls->L;
|
||||
setcdataV(L, tv, cd);
|
||||
setboolV(lj_tab_set(L, ls->fs->kt, tv), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- Jump list handling -------------------------------------------------- */
|
||||
|
||||
/* Get next element in jump list. */
|
||||
@@ -469,6 +484,11 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
|
||||
ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k);
|
||||
else
|
||||
ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
|
||||
#if LJ_HASFFI
|
||||
} else if (e->k == VKCDATA) {
|
||||
ins = BCINS_AD(BC_KCDATA, reg,
|
||||
const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA));
|
||||
#endif
|
||||
} else if (e->k == VRELOCABLE) {
|
||||
setbc_a(bcptr(fs, e), reg);
|
||||
goto noins;
|
||||
@@ -856,7 +876,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
|
||||
if (e->k == VKNIL || e->k == VKFALSE) {
|
||||
e->k = VKTRUE;
|
||||
return;
|
||||
} else if (expr_isk(e)) {
|
||||
} else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) {
|
||||
e->k = VKFALSE;
|
||||
return;
|
||||
} else if (e->k == VJMP) {
|
||||
@@ -872,10 +892,22 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
|
||||
}
|
||||
} else {
|
||||
lua_assert(op == BC_UNM || op == BC_LEN);
|
||||
/* Constant-fold negations. But avoid folding to -0. */
|
||||
if (op == BC_UNM && expr_isnumk_nojump(e) && expr_numV(e) != 0) {
|
||||
setnumV(&e->u.nval, -expr_numV(e));
|
||||
return;
|
||||
if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */
|
||||
#if LJ_HASFFI
|
||||
if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */
|
||||
GCcdata *cd = cdataV(&e->u.nval);
|
||||
int64_t *p = (int64_t *)cdataptr(cd);
|
||||
if (cd->typeid == CTID_COMPLEX_DOUBLE)
|
||||
p[1] ^= (int64_t)U64x(80000000,00000000);
|
||||
else
|
||||
*p = -*p;
|
||||
return;
|
||||
} else
|
||||
#endif
|
||||
if (expr_isnumk(e) && expr_numV(e) != 0) { /* Avoid folding to -0. */
|
||||
e->u.nval.u64 ^= U64x(80000000,00000000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
expr_toanyreg(fs, e);
|
||||
}
|
||||
@@ -1554,8 +1586,8 @@ static void expr_simple(LexState *ls, ExpDesc *v)
|
||||
{
|
||||
switch (ls->token) {
|
||||
case TK_number:
|
||||
expr_init(v, VKNUM, 0);
|
||||
setnumV(&v->u.nval, numV(&ls->tokenval));
|
||||
expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0);
|
||||
copyTV(ls->L, &v->u.nval, &ls->tokenval);
|
||||
break;
|
||||
case TK_string:
|
||||
expr_init(v, VKSTR, 0);
|
||||
|
||||
Reference in New Issue
Block a user