FFI: Parse complex and 64 bit integer literals.

This commit is contained in:
Mike Pall 2010-12-24 01:31:39 +01:00
parent 4850865c57
commit 461bf77331
14 changed files with 305 additions and 112 deletions

View File

@ -93,7 +93,8 @@ lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
lj_bc.h lj_traceerr.h lj_lib.h
lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_lex.h lj_parse.h lj_char.h
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h lualib.h \
lj_lex.h lj_parse.h lj_char.h
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_lib.h
@ -118,7 +119,7 @@ lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_dispatch.h lj_traceerr.h
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_state.h \
lj_bc.h lj_lex.h lj_parse.h lj_vm.h lj_vmevent.h
lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h lj_vmevent.h
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \
lj_ffdef.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
@ -151,13 +152,13 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_str.c lj_tab.c \
lj_func.c lj_udata.c lj_meta.c lj_state.c lj_lex.h lj_alloc.h \
lj_dispatch.c lj_ff.h lj_ffdef.h luajit.h lj_vmevent.c lj_vmevent.h \
lj_api.c lj_parse.h lj_lex.c lj_parse.c lj_ctype.c lj_cdata.c lj_cconv.h \
lj_cconv.c lj_cparse.c lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_iropt.h \
lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \
lj_opt_loop.c lj_snap.h lj_mcode.c lj_mcode.h lj_snap.c lj_target.h \
lj_target_*.h lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \
lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_trace.c \
lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c lualib.h \
lj_api.c lj_parse.h lj_lex.c lualib.h lj_parse.c lj_ctype.c lj_cdata.c \
lj_cconv.h lj_cconv.c lj_cparse.c lj_cparse.h lj_lib.c lj_lib.h lj_ir.c \
lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c \
lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_mcode.c lj_mcode.h lj_snap.c \
lj_target.h lj_target_*.h lj_record.c lj_record.h lj_ffrecord.h \
lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h \
lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c \
lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c lib_os.c \
lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c lib_init.c
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h

View File

@ -207,10 +207,10 @@ static int build_code(BuildCtx *ctx)
int32_t ofs = dasm_getpclabel(Dst, i);
if (ofs < 0) return 0x22000000|i;
ctx->bc_ofs[i] = ofs;
#if !LJ_HASJIT
if (!(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP))
#endif
if ((LJ_HASJIT ||
!(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP)) &&
(LJ_HASFFI || i != BC_KCDATA))
sym_insert(ctx, ofs, LABEL_PREFIX_BC, bc_names[i]);
}

View File

@ -2430,6 +2430,19 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| evstddx TMP0, BASE, RA
| ins_next2
break;
case BC_KCDATA:
#if LJ_HASFFI
| // RA = dst*8, RD = cdata_const*8 (~)
| ins_next1
| srwi TMP1, RD, 1
| subfic TMP1, TMP1, -4
| lwzx TMP0, KBASE, TMP1 // KBASE-4-cdata_const*4
| li TMP2, LJ_TCDATA
| evmergelo TMP0, TMP2, TMP0
| evstddx TMP0, BASE, RA
| ins_next2
#endif
break;
case BC_KSHORT:
| // RA = dst*8, RD = int16_literal*8
| srwi TMP1, RD, 3

View File

@ -12,7 +12,7 @@
#define DASM_SECTION_CODE_OP 0
#define DASM_SECTION_CODE_SUB 1
#define DASM_MAXSECTION 2
static const unsigned int build_actionlist[4928] = {
static const unsigned int build_actionlist[4947] = {
0x00010001,
0x00060014,
0x72000000,
@ -3372,6 +3372,25 @@ static const unsigned int build_actionlist[4928] = {
0x7c0903a6,
0x4e800420,
0x00000000,
0x80f00000,
0x3a100004,
0x5588007e,
0x000900ab,
0x2108fffc,
0x7c0f402e,
0x39200000,
0x00098200,
0x1009022d,
0x100ea320,
0x54e815ba,
0x54ea5d78,
0x54ec9b78,
0x7c11402e,
0x54f4dd78,
0x54eb9d78,
0x7c0903a6,
0x4e800420,
0x00000000,
0x558800fe,
0x000900ab,
0x7d080734,
@ -5619,158 +5638,163 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
case BC_KSTR:
dasm_put(Dst, 3342, 32-1);
break;
case BC_KCDATA:
#if LJ_HASFFI
dasm_put(Dst, 3359, 32-1, LJ_TCDATA);
#endif
break;
case BC_KSHORT:
dasm_put(Dst, 3359, 32-3);
dasm_put(Dst, 3378, 32-3);
break;
case BC_KNUM:
dasm_put(Dst, 3375);
dasm_put(Dst, 3394);
break;
case BC_KPRI:
dasm_put(Dst, 3388, 32-3);
dasm_put(Dst, 3407, 32-3);
break;
case BC_KNIL:
dasm_put(Dst, 3403);
dasm_put(Dst, 3422);
break;
/* -- Upvalue and function ops ------------------------------------------ */
case BC_UGET:
dasm_put(Dst, 3422, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
dasm_put(Dst, 3441, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
break;
case BC_USETV:
dasm_put(Dst, 3443, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, DtA(->closed), -LJ_TISNUM, LJ_TISGCV - LJ_TISNUM, Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
dasm_put(Dst, 3462, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, DtA(->closed), -LJ_TISNUM, LJ_TISGCV - LJ_TISNUM, Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
break;
case BC_USETS:
dasm_put(Dst, 3495, 32-1, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, Dt5(->marked), DtA(->closed), LJ_GC_WHITES, GG_DISP2G);
dasm_put(Dst, 3514, 32-1, 32-1, offsetof(GCfuncL, uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, Dt5(->marked), DtA(->closed), LJ_GC_WHITES, GG_DISP2G);
break;
case BC_USETN:
dasm_put(Dst, 3544, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
dasm_put(Dst, 3563, 32-1, offsetof(GCfuncL, uvptr), DtA(->v));
break;
case BC_USETP:
dasm_put(Dst, 3565, 32-1, offsetof(GCfuncL, uvptr), 32-3, DtA(->v));
dasm_put(Dst, 3584, 32-1, offsetof(GCfuncL, uvptr), 32-3, DtA(->v));
break;
case BC_UCLO:
dasm_put(Dst, 3588, Dt1(->openupval), 32-1, -(BCBIAS_J*4 >> 16), Dt1(->base), Dt1(->base));
dasm_put(Dst, 3607, Dt1(->openupval), 32-1, -(BCBIAS_J*4 >> 16), Dt1(->base), Dt1(->base));
break;
case BC_FNEW:
dasm_put(Dst, 3618, 32-1, Dt1(->base), Dt1(->base));
dasm_put(Dst, 3637, 32-1, Dt1(->base), Dt1(->base));
break;
/* -- Table ops --------------------------------------------------------- */
case BC_TNEW:
case BC_TDUP:
dasm_put(Dst, 3644, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base));
dasm_put(Dst, 3663, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base));
if (op == BC_TNEW) {
dasm_put(Dst, 3657);
dasm_put(Dst, 3676);
} else {
dasm_put(Dst, 3665, 32-1);
dasm_put(Dst, 3684, 32-1);
}
dasm_put(Dst, 3672, Dt1(->base));
dasm_put(Dst, 3691, Dt1(->base));
break;
case BC_GGET:
case BC_GSET:
dasm_put(Dst, 3695, 32-1, Dt7(->env));
dasm_put(Dst, 3714, 32-1, Dt7(->env));
if (op == BC_GGET) {
dasm_put(Dst, 3703);
dasm_put(Dst, 3722);
} else {
dasm_put(Dst, 3706);
dasm_put(Dst, 3725);
}
break;
case BC_TGETV:
dasm_put(Dst, 3709, Dt6(->asize), Dt6(->array), 31-3, Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
dasm_put(Dst, 3728, Dt6(->asize), Dt6(->array), 31-3, Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
break;
case BC_TGETS:
dasm_put(Dst, 3767, 32-1, Dt6(->hmask), Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), DtB(->val), DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
dasm_put(Dst, 3831);
dasm_put(Dst, 3786, 32-1, Dt6(->hmask), Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), DtB(->val), DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
dasm_put(Dst, 3850);
break;
case BC_TGETB:
dasm_put(Dst, 3836, 32-3, Dt6(->asize), Dt6(->array), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
dasm_put(Dst, 3855, 32-3, Dt6(->asize), Dt6(->array), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
break;
case BC_TSETV:
dasm_put(Dst, 3880, Dt6(->asize), Dt6(->array), 31-3, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex);
dasm_put(Dst, 3947, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
dasm_put(Dst, 3899, Dt6(->asize), Dt6(->array), 31-3, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex);
dasm_put(Dst, 3966, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
break;
case BC_TSETS:
dasm_put(Dst, 3959, 32-1, Dt6(->hmask), Dt5(->hash), Dt6(->node), Dt6(->nomm), 31-5, 31-3, Dt6(->marked), DtB(->key), DtB(->val), LJ_GC_BLACK, DtB(->val), Dt6(->metatable));
dasm_put(Dst, 4020, Dt6(->nomm), 1<<MM_newindex, DtB(->next), Dt6(->metatable), DISPATCH_GL(tmptv), Dt1(->base), Dt6(->nomm), 1<<MM_newindex, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain));
dasm_put(Dst, 4071, Dt6(->marked), Dt6(->gclist));
dasm_put(Dst, 3978, 32-1, Dt6(->hmask), Dt5(->hash), Dt6(->node), Dt6(->nomm), 31-5, 31-3, Dt6(->marked), DtB(->key), DtB(->val), LJ_GC_BLACK, DtB(->val), Dt6(->metatable));
dasm_put(Dst, 4039, Dt6(->nomm), 1<<MM_newindex, DtB(->next), Dt6(->metatable), DISPATCH_GL(tmptv), Dt1(->base), Dt6(->nomm), 1<<MM_newindex, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain));
dasm_put(Dst, 4090, Dt6(->marked), Dt6(->gclist));
break;
case BC_TSETB:
dasm_put(Dst, 4078, 32-3, Dt6(->asize), Dt6(->array), Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked));
dasm_put(Dst, 4138, Dt6(->gclist));
dasm_put(Dst, 4097, 32-3, Dt6(->asize), Dt6(->array), Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked));
dasm_put(Dst, 4157, Dt6(->gclist));
break;
case BC_TSETM:
dasm_put(Dst, 4143, 32-3, Dt6(->asize), 31-3, Dt6(->marked), Dt6(->array), LJ_GC_BLACK, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
dasm_put(Dst, 4212);
dasm_put(Dst, 4162, 32-3, Dt6(->asize), 31-3, Dt6(->marked), Dt6(->array), LJ_GC_BLACK, Dt1(->base), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist));
dasm_put(Dst, 4231);
break;
/* -- Calls and vararg handling ----------------------------------------- */
case BC_CALLM:
dasm_put(Dst, 4215);
dasm_put(Dst, 4234);
break;
case BC_CALL:
dasm_put(Dst, 4217, Dt7(->pc));
dasm_put(Dst, 4236, Dt7(->pc));
break;
case BC_CALLMT:
dasm_put(Dst, 4237);
dasm_put(Dst, 4256);
break;
case BC_CALLT:
dasm_put(Dst, 4239, FRAME_TYPE, Dt7(->ffid), FRAME_VARG, Dt7(->pc), -4-8, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
dasm_put(Dst, 4304, FRAME_TYPE);
dasm_put(Dst, 4258, FRAME_TYPE, Dt7(->ffid), FRAME_VARG, Dt7(->pc), -4-8, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
dasm_put(Dst, 4323, FRAME_TYPE);
break;
case BC_ITERC:
dasm_put(Dst, 4311, Dt7(->pc));
dasm_put(Dst, 4330, Dt7(->pc));
break;
case BC_ITERN:
#if LJ_HASJIT
#endif
dasm_put(Dst, 4337, Dt6(->asize), Dt6(->array), 31-3, -(BCBIAS_J*4 >> 16), Dt6(->hmask), Dt6(->node), 31-5, 31-3, DtB(->key), -(BCBIAS_J*4 >> 16));
dasm_put(Dst, 4416);
dasm_put(Dst, 4356, Dt6(->asize), Dt6(->array), 31-3, -(BCBIAS_J*4 >> 16), Dt6(->hmask), Dt6(->node), 31-5, 31-3, DtB(->key), -(BCBIAS_J*4 >> 16));
dasm_put(Dst, 4435);
break;
case BC_ISNEXT:
dasm_put(Dst, 4420, LJ_TTAB, LJ_TFUNC, LJ_TNIL, Dt8(->ffid), FF_next_N, 32-1, -(BCBIAS_J*4 >> 16), BC_JMP, BC_ITERC, -(BCBIAS_J*4 >> 16));
dasm_put(Dst, 4439, LJ_TTAB, LJ_TFUNC, LJ_TNIL, Dt8(->ffid), FF_next_N, 32-1, -(BCBIAS_J*4 >> 16), BC_JMP, BC_ITERC, -(BCBIAS_J*4 >> 16));
break;
case BC_VARG:
dasm_put(Dst, 4471, FRAME_VARG, Dt1(->maxstack), Dt1(->top), Dt1(->base), 32-3, Dt1(->base));
dasm_put(Dst, 4551);
dasm_put(Dst, 4490, FRAME_VARG, Dt1(->maxstack), Dt1(->top), Dt1(->base), 32-3, Dt1(->base));
dasm_put(Dst, 4570);
break;
/* -- Returns ----------------------------------------------------------- */
case BC_RETM:
dasm_put(Dst, 4557);
dasm_put(Dst, 4576);
break;
case BC_RET:
dasm_put(Dst, 4559, FRAME_TYPE, FRAME_VARG, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
dasm_put(Dst, 4578, FRAME_TYPE, FRAME_VARG, Dt7(->pc), PC2PROTO(k), FRAME_TYPEP);
break;
case BC_RET0: case BC_RET1:
dasm_put(Dst, 4629, FRAME_TYPE, FRAME_VARG);
dasm_put(Dst, 4648, FRAME_TYPE, FRAME_VARG);
if (op == BC_RET1) {
dasm_put(Dst, 4642);
dasm_put(Dst, 4661);
}
dasm_put(Dst, 4645, Dt7(->pc), PC2PROTO(k));
dasm_put(Dst, 4664, Dt7(->pc), PC2PROTO(k));
break;
/* -- Loops and branches ------------------------------------------------ */
case BC_FORL:
#if LJ_HASJIT
dasm_put(Dst, 4673);
dasm_put(Dst, 4692);
#endif
break;
@ -5782,35 +5806,35 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
case BC_FORI:
case BC_IFORL:
vk = (op == BC_IFORL || op == BC_JFORL);
dasm_put(Dst, 4675, FORL_IDX*8, FORL_STEP*8, FORL_STOP*8);
dasm_put(Dst, 4694, FORL_IDX*8, FORL_STEP*8, FORL_STOP*8);
if (!vk) {
dasm_put(Dst, 4683);
dasm_put(Dst, 4702);
}
if (vk) {
dasm_put(Dst, 4691, FORL_IDX*8);
dasm_put(Dst, 4710, FORL_IDX*8);
}
dasm_put(Dst, 4695, FORL_EXT*8);
dasm_put(Dst, 4714, FORL_EXT*8);
if (op != BC_JFORL) {
dasm_put(Dst, 4703, 32-1);
dasm_put(Dst, 4722, 32-1);
if (op == BC_JFORI) {
dasm_put(Dst, 4707, -(BCBIAS_J*4 >> 16));
dasm_put(Dst, 4726, -(BCBIAS_J*4 >> 16));
} else {
dasm_put(Dst, 4710, -(BCBIAS_J*4 >> 16));
dasm_put(Dst, 4729, -(BCBIAS_J*4 >> 16));
}
}
if (op == BC_FORI) {
dasm_put(Dst, 4713);
dasm_put(Dst, 4732);
} else if (op == BC_IFORL) {
dasm_put(Dst, 4715);
dasm_put(Dst, 4734);
} else {
dasm_put(Dst, 4717, BC_JLOOP);
dasm_put(Dst, 4736, BC_JLOOP);
}
dasm_put(Dst, 4720);
dasm_put(Dst, 4739);
break;
case BC_ITERL:
#if LJ_HASJIT
dasm_put(Dst, 4735);
dasm_put(Dst, 4754);
#endif
break;
@ -5819,40 +5843,40 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
break;
#endif
case BC_IITERL:
dasm_put(Dst, 4737);
dasm_put(Dst, 4756);
if (op == BC_JITERL) {
dasm_put(Dst, 4743);
dasm_put(Dst, 4762);
} else {
dasm_put(Dst, 4745, 32-1, -(BCBIAS_J*4 >> 16));
dasm_put(Dst, 4764, 32-1, -(BCBIAS_J*4 >> 16));
}
dasm_put(Dst, 4752);
dasm_put(Dst, 4771);
break;
case BC_LOOP:
#if LJ_HASJIT
dasm_put(Dst, 4764);
dasm_put(Dst, 4783);
#endif
break;
case BC_ILOOP:
dasm_put(Dst, 4766);
dasm_put(Dst, 4785);
break;
case BC_JLOOP:
#if LJ_HASJIT
dasm_put(Dst, 4777);
dasm_put(Dst, 4796);
#endif
break;
case BC_JMP:
dasm_put(Dst, 4779, 32-1, -(BCBIAS_J*4 >> 16));
dasm_put(Dst, 4798, 32-1, -(BCBIAS_J*4 >> 16));
break;
/* -- Function headers -------------------------------------------------- */
case BC_FUNCF:
#if LJ_HASJIT
dasm_put(Dst, 4795);
dasm_put(Dst, 4814);
#endif
case BC_FUNCV: /* NYI: compiled vararg functions. */
break;
@ -5862,38 +5886,38 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
break;
#endif
case BC_IFUNCF:
dasm_put(Dst, 4797, Dt1(->maxstack), -4+PC2PROTO(numparams), -4+PC2PROTO(k), 31-3);
dasm_put(Dst, 4816, Dt1(->maxstack), -4+PC2PROTO(numparams), -4+PC2PROTO(k), 31-3);
if (op == BC_JFUNCF) {
dasm_put(Dst, 4815);
dasm_put(Dst, 4834);
} else {
dasm_put(Dst, 4817);
dasm_put(Dst, 4836);
}
dasm_put(Dst, 4826);
dasm_put(Dst, 4845);
break;
case BC_JFUNCV:
#if !LJ_HASJIT
break;
#endif
dasm_put(Dst, 4832);
dasm_put(Dst, 4851);
break; /* NYI: compiled vararg functions. */
case BC_IFUNCV:
dasm_put(Dst, 4834, Dt1(->maxstack), 8+FRAME_VARG, -4+PC2PROTO(k), -4+PC2PROTO(numparams));
dasm_put(Dst, 4853, Dt1(->maxstack), 8+FRAME_VARG, -4+PC2PROTO(k), -4+PC2PROTO(numparams));
break;
case BC_FUNCC:
case BC_FUNCCW:
if (op == BC_FUNCC) {
dasm_put(Dst, 4884, Dt8(->f));
} else {
dasm_put(Dst, 4887, DISPATCH_GL(wrapf));
}
dasm_put(Dst, 4890, Dt1(->maxstack), Dt1(->base), Dt1(->top), ~LJ_VMST_C);
if (op == BC_FUNCCW) {
dasm_put(Dst, 4903, Dt8(->f));
} else {
dasm_put(Dst, 4906, DISPATCH_GL(wrapf));
}
dasm_put(Dst, 4906, DISPATCH_GL(vmstate), Dt1(->top), 31-3, Dt1(->base), ~LJ_VMST_INTERP, DISPATCH_GL(vmstate));
dasm_put(Dst, 4909, Dt1(->maxstack), Dt1(->base), Dt1(->top), ~LJ_VMST_C);
if (op == BC_FUNCCW) {
dasm_put(Dst, 4922, Dt8(->f));
}
dasm_put(Dst, 4925, DISPATCH_GL(vmstate), Dt1(->top), 31-3, Dt1(->base), ~LJ_VMST_INTERP, DISPATCH_GL(vmstate));
break;
/* ---------------------------------------------------------------------- */
@ -5913,7 +5937,7 @@ static int build_backend(BuildCtx *ctx)
build_subroutines(ctx);
dasm_put(Dst, 4927);
dasm_put(Dst, 4946);
for (op = 0; op < BC__MAX; op++)
build_ins(ctx, (BCOp)op, op);

View File

@ -1862,6 +1862,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
case BC_KSTR:
dasm_put(Dst, 10553, LJ_TSTR);
break;
case BC_KCDATA:
#if LJ_HASFFI
dasm_put(Dst, 10553, LJ_TCDATA);
#endif
break;
case BC_KSHORT:
if (sse) {
dasm_put(Dst, 10590);

View File

@ -1863,6 +1863,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
case BC_KSTR:
dasm_put(Dst, 10534, LJ_TSTR);
break;
case BC_KCDATA:
#if LJ_HASFFI
dasm_put(Dst, 10534, LJ_TCDATA);
#endif
break;
case BC_KSHORT:
if (sse) {
dasm_put(Dst, 10569);

View File

@ -3795,6 +3795,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
| mov [BASE+RA*8], RD
| ins_next
break;
case BC_KCDATA:
#if LJ_HASFFI
| ins_AND // RA = dst, RD = cdata const (~)
| mov RD, [KBASE+RD*4]
| mov dword [BASE+RA*8+4], LJ_TCDATA
| mov [BASE+RA*8], RD
| ins_next
#endif
break;
case BC_KSHORT:
| ins_AD // RA = dst, RD = signed int16 literal
if (sse) {

View File

@ -1982,6 +1982,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse)
case BC_KSTR:
dasm_put(Dst, 11907, LJ_TSTR);
break;
case BC_KCDATA:
#if LJ_HASFFI
dasm_put(Dst, 11907, LJ_TCDATA);
#endif
break;
case BC_KSHORT:
if (sse) {
dasm_put(Dst, 11940);

View File

@ -474,7 +474,8 @@ LUALIB_API int luaopen_ffi(lua_State *L)
lj_ctype_init(L);
LJ_LIB_REG_(L, NULL, ffi_meta);
/* NOBARRIER: basemt is a GC root. */
setgcref(basemt_it(G(L), LJ_TCDATA), obj2gco(tabV(L->top-1)));
L->top--;
setgcref(basemt_it(G(L), LJ_TCDATA), obj2gco(tabV(L->top)));
lua_pushliteral(L, LJ_OS_NAME);
lua_pushliteral(L, LJ_ARCH_NAME);
LJ_LIB_REG_(L, NULL, ffi); /* Note: no global "ffi" created! */

View File

@ -121,6 +121,7 @@
\
/* Constant ops. */ \
_(KSTR, dst, ___, str, ___) \
_(KCDATA, dst, ___, cdata, ___) \
_(KSHORT, dst, ___, lits, ___) \
_(KNUM, dst, ___, num, ___) \
_(KPRI, dst, ___, pri, ___) \
@ -234,7 +235,7 @@ enum {
/* Bytecode operand modes. ORDER BCMode */
typedef enum {
BCMnone, BCMdst, BCMbase, BCMvar, BCMrbase, BCMuv, /* Mode A must be <= 7 */
BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc, BCMjump,
BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc, BCMjump, BCMcdata,
BCM_max
} BCMode;
#define BCM___ BCMnone

View File

@ -45,6 +45,15 @@ static LJ_AINLINE GCcdata *lj_cdata_new(CTState *cts, CTypeID id, CTSize sz)
return cd;
}
/* Variant which works without a valid CTState. */
static LJ_AINLINE GCcdata *lj_cdata_new_(lua_State *L, CTypeID id, CTSize sz)
{
GCcdata *cd = (GCcdata *)lj_mem_newgco(L, sizeof(GCcdata) + sz);
cd->gct = ~LJ_TCDATA;
cd->typeid = id;
return cd;
}
LJ_FUNC GCcdata *lj_cdata_newref(CTState *cts, const void *pp, CTypeID id);
LJ_FUNC GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz,
CTSize align);

View File

@ -13,6 +13,12 @@
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_str.h"
#if LJ_HASFFI
#include "lj_tab.h"
#include "lj_ctype.h"
#include "lj_cdata.h"
#include "lualib.h"
#endif
#include "lj_lex.h"
#include "lj_parse.h"
#include "lj_char.h"
@ -77,7 +83,64 @@ static void inclinenumber(LexState *ls)
/* -- Scanner for terminals ----------------------------------------------- */
static void read_numeral(LexState *ls, TValue *tv)
#if LJ_HASFFI
/* Load FFI library on-demand. Needed if we create cdata objects. */
static void lex_loadffi(lua_State *L)
{
cTValue *tmp;
luaopen_ffi(L);
tmp = lj_tab_getstr(tabV(registry(L)), lj_str_newlit(L, "_LOADED"));
if (tmp && tvistab(tmp)) {
GCtab *t = tabV(tmp);
copyTV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "ffi")), L->top-1);
lj_gc_anybarriert(L, t);
}
L->top--;
}
/* Parse 64 bit integer. */
static int lex_number64(LexState *ls, TValue *tv)
{
uint64_t n = 0;
uint8_t *p = (uint8_t *)ls->sb.buf;
CTypeID id = CTID_INT64;
GCcdata *cd;
int numl = 0;
if (p[0] == '0' && (p[1] & ~0x20) == 'X') { /* Hexadecimal. */
p += 2;
if (!lj_char_isxdigit(*p)) return 0;
do {
n = n*16 + (*p & 15);
if (!lj_char_isdigit(*p)) n += 9;
p++;
} while (lj_char_isxdigit(*p));
} else { /* Decimal. */
if (!lj_char_isdigit(*p)) return 0;
do {
n = n*10 + (*p - '0');
p++;
} while (lj_char_isdigit(*p));
}
for (;;) { /* Parse suffixes. */
if ((*p & ~0x20) == 'U')
id = CTID_UINT64;
else if ((*p & ~0x20) == 'L')
numl++;
else
break;
p++;
}
if (numl != 2 || *p != '\0') return 0;
/* Return cdata holding a 64 bit integer. */
cd = lj_cdata_new_(ls->L, id, 8);
*(uint64_t *)cdataptr(cd) = n;
lj_parse_keepcdata(ls, tv, cd);
return 1; /* Ok. */
}
#endif
/* Parse a number literal. */
static void lex_number(LexState *ls, TValue *tv)
{
int c;
lua_assert(lj_char_isdigit(ls->current));
@ -87,8 +150,30 @@ static void read_numeral(LexState *ls, TValue *tv)
} while (lj_char_isident(ls->current) || ls->current == '.' ||
((ls->current == '-' || ls->current == '+') &&
((c & ~0x20) == 'E' || (c & ~0x20) == 'P')));
#if LJ_HASFFI
c &= ~0x20;
if ((c == 'I' || c == 'L' || c == 'U') && !ctype_ctsG(G(ls->L)))
lex_loadffi(ls->L);
if (c == 'I') /* Parse imaginary part of complex number. */
ls->sb.n--;
#endif
save(ls, '\0');
if (!lj_str_numconv(ls->sb.buf, tv))
#if LJ_HASFFI
if ((c == 'L' || c == 'U') && lex_number64(ls, tv)) { /* Parse 64 bit int. */
return;
} else
#endif
if (lj_str_numconv(ls->sb.buf, tv)) {
#if LJ_HASFFI
if (c == 'I') { /* Return cdata holding a complex number. */
GCcdata *cd = lj_cdata_new_(ls->L, CTID_COMPLEX_DOUBLE, 2*sizeof(double));
((double *)cdataptr(cd))[0] = 0;
((double *)cdataptr(cd))[1] = tv->n;
lj_parse_keepcdata(ls, tv, cd);
}
#endif
return;
}
lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
}
@ -224,7 +309,7 @@ static int llex(LexState *ls, TValue *tv)
if (lj_char_isident(ls->current)) {
GCstr *s;
if (lj_char_isdigit(ls->current)) { /* Numeric literal. */
read_numeral(ls, tv);
lex_number(ls, tv);
return TK_number;
}
/* Identifier or reserved word. */
@ -306,7 +391,7 @@ static int llex(LexState *ls, TValue *tv)
} else if (!lj_char_isdigit(ls->current)) {
return '.';
} else {
read_numeral(ls, tv);
lex_number(ls, tv);
return TK_number;
}
case END_OF_STREAM:

View File

@ -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 */
@ -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));
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);

View File

@ -11,5 +11,8 @@
LJ_FUNC GCproto *lj_parse(LexState *ls);
LJ_FUNC GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t l);
#if LJ_HASFFI
LJ_FUNC void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd);
#endif
#endif