aboutsummaryrefslogtreecommitdiff
path: root/src/lj_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r--src/lj_parse.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c
index d93ed990..22241b24 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -17,6 +17,9 @@
17#include "lj_func.h" 17#include "lj_func.h"
18#include "lj_state.h" 18#include "lj_state.h"
19#include "lj_bc.h" 19#include "lj_bc.h"
20#if LJ_HASFFI
21#include "lj_ctype.h"
22#endif
20#include "lj_lex.h" 23#include "lj_lex.h"
21#include "lj_parse.h" 24#include "lj_parse.h"
22#include "lj_vm.h" 25#include "lj_vm.h"
@@ -33,6 +36,7 @@ typedef enum {
33 VKSTR, /* sval = string value */ 36 VKSTR, /* sval = string value */
34 VKNUM, /* nval = number value */ 37 VKNUM, /* nval = number value */
35 VKLAST = VKNUM, 38 VKLAST = VKNUM,
39 VKCDATA, /* nval = cdata value, not treated as a constant expression */
36 /* Non-constant expressions follow: */ 40 /* Non-constant expressions follow: */
37 VLOCAL, /* info = local register */ 41 VLOCAL, /* info = local register */
38 VUPVAL, /* info = upvalue index */ 42 VUPVAL, /* info = upvalue index */
@@ -61,7 +65,7 @@ typedef struct ExpDesc {
61} ExpDesc; 65} ExpDesc;
62 66
63/* Macros for expressions. */ 67/* Macros for expressions. */
64#define expr_hasjump(e) ((e)->t != (e)->f) 68#define expr_hasjump(e) ((e)->t != (e)->f)
65 69
66#define expr_isk(e) ((e)->k <= VKLAST) 70#define expr_isk(e) ((e)->k <= VKLAST)
67#define expr_isk_nojump(e) (expr_isk(e) && !expr_hasjump(e)) 71#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)
216 return s; 220 return s;
217} 221}
218 222
223#if LJ_HASFFI
224/* Anchor cdata to avoid GC. */
225void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd)
226{
227 /* NOBARRIER: the key is new or kept alive. */
228 lua_State *L = ls->L;
229 setcdataV(L, tv, cd);
230 setboolV(lj_tab_set(L, ls->fs->kt, tv), 1);
231}
232#endif
233
219/* -- Jump list handling -------------------------------------------------- */ 234/* -- Jump list handling -------------------------------------------------- */
220 235
221/* Get next element in jump list. */ 236/* Get next element in jump list. */
@@ -469,6 +484,11 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
469 ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); 484 ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k);
470 else 485 else
471 ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); 486 ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
487#if LJ_HASFFI
488 } else if (e->k == VKCDATA) {
489 ins = BCINS_AD(BC_KCDATA, reg,
490 const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA));
491#endif
472 } else if (e->k == VRELOCABLE) { 492 } else if (e->k == VRELOCABLE) {
473 setbc_a(bcptr(fs, e), reg); 493 setbc_a(bcptr(fs, e), reg);
474 goto noins; 494 goto noins;
@@ -856,7 +876,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
856 if (e->k == VKNIL || e->k == VKFALSE) { 876 if (e->k == VKNIL || e->k == VKFALSE) {
857 e->k = VKTRUE; 877 e->k = VKTRUE;
858 return; 878 return;
859 } else if (expr_isk(e)) { 879 } else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) {
860 e->k = VKFALSE; 880 e->k = VKFALSE;
861 return; 881 return;
862 } else if (e->k == VJMP) { 882 } else if (e->k == VJMP) {
@@ -872,10 +892,22 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
872 } 892 }
873 } else { 893 } else {
874 lua_assert(op == BC_UNM || op == BC_LEN); 894 lua_assert(op == BC_UNM || op == BC_LEN);
875 /* Constant-fold negations. But avoid folding to -0. */ 895 if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */
876 if (op == BC_UNM && expr_isnumk_nojump(e) && expr_numV(e) != 0) { 896#if LJ_HASFFI
877 setnumV(&e->u.nval, -expr_numV(e)); 897 if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */
878 return; 898 GCcdata *cd = cdataV(&e->u.nval);
899 int64_t *p = (int64_t *)cdataptr(cd);
900 if (cd->typeid == CTID_COMPLEX_DOUBLE)
901 p[1] ^= (int64_t)U64x(80000000,00000000);
902 else
903 *p = -*p;
904 return;
905 } else
906#endif
907 if (expr_isnumk(e) && expr_numV(e) != 0) { /* Avoid folding to -0. */
908 e->u.nval.u64 ^= U64x(80000000,00000000);
909 return;
910 }
879 } 911 }
880 expr_toanyreg(fs, e); 912 expr_toanyreg(fs, e);
881 } 913 }
@@ -1554,8 +1586,8 @@ static void expr_simple(LexState *ls, ExpDesc *v)
1554{ 1586{
1555 switch (ls->token) { 1587 switch (ls->token) {
1556 case TK_number: 1588 case TK_number:
1557 expr_init(v, VKNUM, 0); 1589 expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0);
1558 setnumV(&v->u.nval, numV(&ls->tokenval)); 1590 copyTV(ls->L, &v->u.nval, &ls->tokenval);
1559 break; 1591 break;
1560 case TK_string: 1592 case TK_string:
1561 expr_init(v, VKSTR, 0); 1593 expr_init(v, VKSTR, 0);