From 461bf7733164c1c02f3e3001faef6eb028cd6e9e Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Fri, 24 Dec 2010 01:31:39 +0100 Subject: FFI: Parse complex and 64 bit integer literals. --- src/Makefile.dep | 19 +++--- src/buildvm.c | 8 +-- src/buildvm_ppc.dasc | 13 ++++ src/buildvm_ppcspe.h | 188 +++++++++++++++++++++++++++++---------------------- src/buildvm_x64.h | 5 ++ src/buildvm_x64win.h | 5 ++ src/buildvm_x86.dasc | 9 +++ src/buildvm_x86.h | 5 ++ src/lib_ffi.c | 3 +- src/lj_bc.h | 3 +- src/lj_cdata.h | 9 +++ src/lj_lex.c | 95 ++++++++++++++++++++++++-- src/lj_parse.c | 48 ++++++++++--- src/lj_parse.h | 3 + 14 files changed, 303 insertions(+), 110 deletions(-) diff --git a/src/Makefile.dep b/src/Makefile.dep index 6a5d208a..3e202537 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -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 diff --git a/src/buildvm.c b/src/buildvm.c index 72e612c1..1681b592 100644 --- a/src/buildvm.c +++ b/src/buildvm.c @@ -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]); } diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc index 108363e5..a81335db 100644 --- a/src/buildvm_ppc.dasc +++ b/src/buildvm_ppc.dasc @@ -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 diff --git a/src/buildvm_ppcspe.h b/src/buildvm_ppcspe.h index 0855fda8..8a10c24a 100644 --- a/src/buildvm_ppcspe.h +++ b/src/buildvm_ppcspe.h @@ -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<asize), Dt6(->array), 31-3, Dt6(->metatable), Dt6(->nomm), 1<hmask), Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), DtB(->val), DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<hmask), Dt5(->hash), Dt6(->node), 31-5, 31-3, DtB(->key), DtB(->val), DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<asize), Dt6(->array), Dt6(->metatable), Dt6(->nomm), 1<asize), Dt6(->array), Dt6(->metatable), Dt6(->nomm), 1<asize), Dt6(->array), 31-3, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<marked), Dt6(->gclist)); + dasm_put(Dst, 3899, Dt6(->asize), Dt6(->array), 31-3, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<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<next), Dt6(->metatable), DISPATCH_GL(tmptv), Dt1(->base), Dt6(->nomm), 1<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<next), Dt6(->metatable), DISPATCH_GL(tmptv), Dt1(->base), Dt6(->nomm), 1<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<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<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)); + dasm_put(Dst, 4903, Dt8(->f)); } else { - dasm_put(Dst, 4887, DISPATCH_GL(wrapf)); + dasm_put(Dst, 4906, DISPATCH_GL(wrapf)); } - dasm_put(Dst, 4890, Dt1(->maxstack), Dt1(->base), Dt1(->top), ~LJ_VMST_C); + dasm_put(Dst, 4909, Dt1(->maxstack), Dt1(->base), Dt1(->top), ~LJ_VMST_C); if (op == BC_FUNCCW) { - dasm_put(Dst, 4903, Dt8(->f)); + dasm_put(Dst, 4922, Dt8(->f)); } - dasm_put(Dst, 4906, DISPATCH_GL(vmstate), Dt1(->top), 31-3, Dt1(->base), ~LJ_VMST_INTERP, DISPATCH_GL(vmstate)); + 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); diff --git a/src/buildvm_x64.h b/src/buildvm_x64.h index c40abbd8..73cbbb6d 100644 --- a/src/buildvm_x64.h +++ b/src/buildvm_x64.h @@ -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); diff --git a/src/buildvm_x64win.h b/src/buildvm_x64win.h index e855ca8b..94dbe50f 100644 --- a/src/buildvm_x64win.h +++ b/src/buildvm_x64win.h @@ -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); diff --git a/src/buildvm_x86.dasc b/src/buildvm_x86.dasc index 0bd8f304..b4f34782 100644 --- a/src/buildvm_x86.dasc +++ b/src/buildvm_x86.dasc @@ -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) { diff --git a/src/buildvm_x86.h b/src/buildvm_x86.h index 25e4cc8e..555fe67a 100644 --- a/src/buildvm_x86.h +++ b/src/buildvm_x86.h @@ -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); diff --git a/src/lib_ffi.c b/src/lib_ffi.c index ed73a5fe..3ea19dd5 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -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! */ diff --git a/src/lj_bc.h b/src/lj_bc.h index 837316d5..101e2c15 100644 --- a/src/lj_bc.h +++ b/src/lj_bc.h @@ -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 diff --git a/src/lj_cdata.h b/src/lj_cdata.h index 38b6ce16..27b0bf15 100644 --- a/src/lj_cdata.h +++ b/src/lj_cdata.h @@ -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); diff --git a/src/lj_lex.c b/src/lj_lex.c index a115b79a..01e5ce57 100644 --- a/src/lj_lex.c +++ b/src/lj_lex.c @@ -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,9 +150,31 @@ 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)) - lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER); +#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); } static int skip_sep(LexState *ls) @@ -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: 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 @@ #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); diff --git a/src/lj_parse.h b/src/lj_parse.h index 2031eeed..a05cb4ce 100644 --- a/src/lj_parse.h +++ b/src/lj_parse.h @@ -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 -- cgit v1.2.3-55-g6feb