aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/extensions.html25
-rw-r--r--src/Makefile.dep9
-rw-r--r--src/lj_bc.h11
-rw-r--r--src/lj_bcdump.h3
-rw-r--r--src/lj_bcwrite.c5
-rw-r--r--src/lj_carith.c31
-rw-r--r--src/lj_carith.h1
-rw-r--r--src/lj_crecord.c35
-rw-r--r--src/lj_crecord.h5
-rw-r--r--src/lj_dispatch.h1
-rw-r--r--src/lj_errmsg.h4
-rw-r--r--src/lj_ffrecord.c2
-rw-r--r--src/lj_ir.h2
-rw-r--r--src/lj_lex.c49
-rw-r--r--src/lj_lex.h12
-rw-r--r--src/lj_meta.c75
-rw-r--r--src/lj_meta.h2
-rw-r--r--src/lj_obj.h1
-rw-r--r--src/lj_opt_fold.c2
-rw-r--r--src/lj_parse.c781
-rw-r--r--src/lj_record.c40
-rw-r--r--src/vm_arm.dasc75
-rw-r--r--src/vm_arm64.dasc64
-rw-r--r--src/vm_mips.dasc75
-rw-r--r--src/vm_mips64.dasc77
-rw-r--r--src/vm_ppc.dasc100
-rw-r--r--src/vm_x64.dasc125
-rw-r--r--src/vm_x86.dasc132
28 files changed, 1510 insertions, 234 deletions
diff --git a/doc/extensions.html b/doc/extensions.html
index 16e88505b..4668e192e 100644
--- a/doc/extensions.html
+++ b/doc/extensions.html
@@ -411,6 +411,31 @@ LuaJIT supports some extensions from Lua 5.3:
411</li> 411</li>
412</ul> 412</ul>
413 413
414<h2 id="lj30_bp_syntax">Backported Syntax Extensions from LuaJIT 3.0</h2>
415<p>
416LuaJIT 2.1 supports some
417<a href="https://github.com/LuaJIT/LuaJIT/issues/1475#issuecomment-4769582883"><span class="ext">&raquo;</span>&nbsp;syntax extensions backported from LuaJIT&nbsp;3.0</a>:
418</p>
419<ul>
420 <li>Bit Operators: unary <tt>~</tt>, binary <tt>&amp; | ~ &lt;&lt; &gt;&gt; ~&gt;&gt;</tt></li>
421 <li>Customary Operators: <tt>! && || !=</tt></li>
422 <li>Ternary <tt>?:</tt> conditional operator</li>
423 <li>Safe Navigation Operator <tt>?.</tt></li>
424 <li>nil-Coalescing Operator <tt>??</tt></li>
425 <li>Compound Assignment Operators: <tt>+= -= *= /= %= &amp;= |= ~= &lt;&lt;= &gt;&gt;= ~&gt;&gt;= ..=</tt></li>
426 <li><tt>continue</tt> Statement</li>
427 <li><tt>const</tt> Declaration</li>
428 <li>Short Function Expression</li>
429 <li>Underscores in Number Literals</li>
430</ul>
431<p>
432Not backported are:
433bit operator metamethods,
434floor division operator <tt>//</tt>,
435compound assignment metamethods,
436named vararg parameter <tt>...name</tt>.
437</p>
438
414<h2 id="exceptions">C++ Exception Interoperability</h2> 439<h2 id="exceptions">C++ Exception Interoperability</h2>
415<p> 440<p>
416LuaJIT has built-in support for interoperating with C++&nbsp;exceptions. 441LuaJIT has built-in support for interoperating with C++&nbsp;exceptions.
diff --git a/src/Makefile.dep b/src/Makefile.dep
index e10a6b29b..709107c2e 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -149,7 +149,8 @@ lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
149 lj_dispatch.h lj_bc.h lj_traceerr.h lj_prng.h lj_vm.h 149 lj_dispatch.h lj_bc.h lj_traceerr.h lj_prng.h lj_vm.h
150lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 150lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
151 lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \ 151 lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \
152 lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h 152 lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h lj_ctype.h lj_cdata.h \
153 lj_carith.h
153lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h 154lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
154lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 155lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
155 lj_ir.h lj_jit.h lj_iropt.h 156 lj_ir.h lj_jit.h lj_iropt.h
@@ -181,9 +182,9 @@ lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
181 lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h 182 lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h
182lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 183lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
183 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ 184 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
184 lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \ 185 lj_ctype.h lj_gc.h lj_crecord.h lj_jit.h lj_ir.h lj_ffrecord.h lj_ff.h \
185 lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \ 186 lj_ffdef.h lj_debug.h lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h \
186 lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h lj_prng.h 187 lj_traceerr.h lj_record.h lj_snap.h lj_vm.h lj_prng.h
187lj_serialize.o: lj_serialize.c lj_obj.h lua.h luaconf.h lj_def.h \ 188lj_serialize.o: lj_serialize.c lj_obj.h lua.h luaconf.h lj_def.h \
188 lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \ 189 lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
189 lj_udata.h lj_ctype.h lj_cdata.h lj_ir.h lj_serialize.h 190 lj_udata.h lj_ctype.h lj_cdata.h lj_ir.h lj_serialize.h
diff --git a/src/lj_bc.h b/src/lj_bc.h
index 54d529e34..cbadc9abe 100644
--- a/src/lj_bc.h
+++ b/src/lj_bc.h
@@ -98,7 +98,7 @@
98 _(UNM, dst, ___, var, unm) \ 98 _(UNM, dst, ___, var, unm) \
99 _(LEN, dst, ___, var, len) \ 99 _(LEN, dst, ___, var, len) \
100 \ 100 \
101 /* Binary ops. ORDER OPR. VV last, POW must be next. */ \ 101 /* Binary ops. ORDER OPR. ORDER ARITH. VV last, POW must be next. */ \
102 _(ADDVN, dst, var, num, add) \ 102 _(ADDVN, dst, var, num, add) \
103 _(SUBVN, dst, var, num, sub) \ 103 _(SUBVN, dst, var, num, sub) \
104 _(MULVN, dst, var, num, mul) \ 104 _(MULVN, dst, var, num, mul) \
@@ -186,6 +186,15 @@
186 \ 186 \
187 _(JMP, rbase, ___, jump, ___) \ 187 _(JMP, rbase, ___, jump, ___) \
188 \ 188 \
189 /* Bit operators. ORDER OPR. ORDER BIT. */ \
190 _(BNOT, dst, ___, var, ___) \
191 _(BAND, dst, var, var, ___) \
192 _(BOR, dst, var, var, ___) \
193 _(BXOR, dst, var, var, ___) \
194 _(BSHL, dst, var, var, ___) \
195 _(BSHR, dst, var, var, ___) \
196 _(BSAR, dst, var, var, ___) \
197 \
189 /* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \ 198 /* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \
190 _(FUNCF, rbase, ___, ___, ___) \ 199 _(FUNCF, rbase, ___, ___, ___) \
191 _(IFUNCF, rbase, ___, ___, ___) \ 200 _(IFUNCF, rbase, ___, ___, ___) \
diff --git a/src/lj_bcdump.h b/src/lj_bcdump.h
index 074ac0fda..3d2c95aca 100644
--- a/src/lj_bcdump.h
+++ b/src/lj_bcdump.h
@@ -43,8 +43,9 @@
43#define BCDUMP_F_STRIP 0x02 43#define BCDUMP_F_STRIP 0x02
44#define BCDUMP_F_FFI 0x04 44#define BCDUMP_F_FFI 0x04
45#define BCDUMP_F_FR2 0x08 45#define BCDUMP_F_FR2 0x08
46#define BCDUMP_F_BITOP 0x10
46 47
47#define BCDUMP_F_KNOWN (BCDUMP_F_FR2*2-1) 48#define BCDUMP_F_KNOWN (BCDUMP_F_BITOP*2-1)
48 49
49#define BCDUMP_F_DETERMINISTIC 0x80000000 50#define BCDUMP_F_DETERMINISTIC 0x80000000
50 51
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c
index a0230eff5..fb557e588 100644
--- a/src/lj_bcwrite.c
+++ b/src/lj_bcwrite.c
@@ -340,7 +340,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
340 p += 5; /* Leave room for final size. */ 340 p += 5; /* Leave room for final size. */
341 341
342 /* Write prototype header. */ 342 /* Write prototype header. */
343 *p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI)); 343 *p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI|PROTO_BITOP));
344 *p++ = pt->numparams; 344 *p++ = pt->numparams;
345 *p++ = pt->framesize; 345 *p++ = pt->framesize;
346 *p++ = pt->sizeuv; 346 *p++ = pt->sizeuv;
@@ -397,7 +397,8 @@ static void bcwrite_header(BCWriteCtx *ctx)
397 *p++ = BCDUMP_VERSION; 397 *p++ = BCDUMP_VERSION;
398 *p++ = (ctx->flags & (BCDUMP_F_STRIP | BCDUMP_F_FR2)) + 398 *p++ = (ctx->flags & (BCDUMP_F_STRIP | BCDUMP_F_FR2)) +
399 LJ_BE*BCDUMP_F_BE + 399 LJ_BE*BCDUMP_F_BE +
400 ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0); 400 ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0) +
401 ((ctx->pt->flags & PROTO_BITOP) ? BCDUMP_F_BITOP : 0);
401 if (!(ctx->flags & BCDUMP_F_STRIP)) { 402 if (!(ctx->flags & BCDUMP_F_STRIP)) {
402 p = lj_strfmt_wuleb128(p, len); 403 p = lj_strfmt_wuleb128(p, len);
403 p = lj_buf_wmem(p, name, len); 404 p = lj_buf_wmem(p, name, len);
diff --git a/src/lj_carith.c b/src/lj_carith.c
index cb408fb80..10f461580 100644
--- a/src/lj_carith.c
+++ b/src/lj_carith.c
@@ -353,6 +353,37 @@ uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id)
353 } 353 }
354} 354}
355 355
356/* Check bit operator arguments. No coercion from strings. */
357uint64_t lj_carith_checkbit64(lua_State *L, cTValue *o, CTypeID *id)
358{
359 if (tviscdata(o)) {
360 CTState *cts = ctype_cts(L);
361 uint8_t *sp = (uint8_t *)cdataptr(cdataV(o));
362 CTypeID sid = cdataV(o)->ctypeid;
363 CType *s = ctype_get(cts, sid);
364 uint64_t x;
365 if (ctype_isref(s->info)) {
366 sp = *(void **)sp;
367 sid = ctype_cid(s->info);
368 }
369 s = ctype_raw(cts, sid);
370 if (ctype_isenum(s->info)) s = ctype_child(cts, s);
371 if ((s->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
372 CTINFO(CT_NUM, CTF_UNSIGNED) && s->size == 8)
373 *id = CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
374 else if (!*id)
375 *id = CTID_INT64; /* Use int64_t, unless already set. */
376 lj_cconv_ct_ct(cts, ctype_get(cts, *id), s,
377 (uint8_t *)&x, sp, 0);
378 return x;
379 } else if (LJ_LIKELY(tvisint(o))) {
380 return (uint64_t)intV(o); /* Sign-extended. */
381 } else {
382 if (!tvisnum(o)) lj_err_optype(L, o, LJ_ERR_OPARITH);
383 return (uint64_t)lj_num2bit(numV(o)); /* Sign-extended. */
384 }
385}
386
356/* -- 64 bit integer arithmetic helpers ----------------------------------- */ 387/* -- 64 bit integer arithmetic helpers ----------------------------------- */
357 388
358#if LJ_32 && LJ_HASJIT 389#if LJ_32 && LJ_HASJIT
diff --git a/src/lj_carith.h b/src/lj_carith.h
index 93fa41f2b..700e48791 100644
--- a/src/lj_carith.h
+++ b/src/lj_carith.h
@@ -21,6 +21,7 @@ LJ_FUNC uint64_t lj_carith_ror64(uint64_t x, int32_t sh);
21#endif 21#endif
22LJ_FUNC uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op); 22LJ_FUNC uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op);
23LJ_FUNC uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id); 23LJ_FUNC uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id);
24LJ_FUNC uint64_t lj_carith_checkbit64(lua_State *L, cTValue *o, CTypeID *id);
24 25
25#if LJ_32 && LJ_HASJIT 26#if LJ_32 && LJ_HASJIT
26LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k); 27LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 4be36eca6..a8ea419a8 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -1884,24 +1884,23 @@ int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
1884 return 0; 1884 return 0;
1885} 1885}
1886 1886
1887int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd) 1887int recff_bit64_shift(jit_State *J, TRef *rb, TRef *rc,
1888 TValue *rbv, TValue *rcv, IROp op)
1888{ 1889{
1889 CTState *cts = ctype_ctsG(J2G(J)); 1890 CTState *cts = ctype_ctsG(J2G(J));
1890 CTypeID id; 1891 CTypeID id;
1891 TRef tsh = 0; 1892 TRef tsh = 0;
1892 if (J->base[0] && tref_iscdata(J->base[1])) { 1893 if (*rb && tref_iscdata(*rc)) {
1893 tsh = crec_bit64_arg(J, ctype_get(cts, CTID_INT64), 1894 tsh = crec_bit64_arg(J, ctype_get(cts, CTID_INT64), *rc, rcv);
1894 J->base[1], &rd->argv[1]);
1895 if (LJ_32 && !tref_isinteger(tsh)) 1895 if (LJ_32 && !tref_isinteger(tsh))
1896 tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0); 1896 tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
1897 J->base[1] = tsh; 1897 *rc = tsh;
1898 } 1898 }
1899 id = crec_bit64_type(cts, &rd->argv[0]); 1899 id = crec_bit64_type(cts, rbv);
1900 if (id) { 1900 if (id) {
1901 TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]); 1901 TRef tr = crec_bit64_arg(J, ctype_get(cts, id), *rb, rbv);
1902 uint32_t op = rd->data;
1903 IRType t; 1902 IRType t;
1904 if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]); 1903 if (!tsh) tsh = lj_opt_narrow_tobit(J, *rc);
1905 t = tref_isinteger(tsh) ? IRT_INT : tref_type(tsh); 1904 t = tref_isinteger(tsh) ? IRT_INT : tref_type(tsh);
1906 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) && 1905 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
1907 !tref_isk(tsh)) 1906 !tref_isk(tsh))
@@ -1913,7 +1912,7 @@ int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
1913 } 1912 }
1914#endif 1913#endif
1915 tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh); 1914 tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
1916 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); 1915 *rb = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1917 return 1; 1916 return 1;
1918 } 1917 }
1919 return 0; 1918 return 0;
@@ -1955,6 +1954,22 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
1955 return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr); 1954 return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr);
1956} 1955}
1957 1956
1957TRef recff_bit64_bitop(jit_State *J, TRef rb, TRef rc,
1958 TValue *rbv, TValue *rcv, IROp op)
1959{
1960 CTState *cts = ctype_ctsG(J2G(J));
1961 CTypeID id = crec_bit64_type(cts, rbv);
1962 CTypeID id2 = rcv ? crec_bit64_type(cts, rcv) : 0;
1963 CType *ct;
1964 TRef tr, tr2;
1965 if (id < id2) id = id2;
1966 ct = ctype_get(cts, id);
1967 tr = crec_bit64_arg(J, ct, rb, rbv);
1968 tr2 = rcv ? crec_bit64_arg(J, ct, rc, rcv) : 0;
1969 tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tr2);
1970 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1971}
1972
1958/* -- Miscellaneous library functions ------------------------------------- */ 1973/* -- Miscellaneous library functions ------------------------------------- */
1959 1974
1960void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) 1975void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
diff --git a/src/lj_crecord.h b/src/lj_crecord.h
index ad99b7254..ad2d3e252 100644
--- a/src/lj_crecord.h
+++ b/src/lj_crecord.h
@@ -29,8 +29,11 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd);
29LJ_FUNC void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd); 29LJ_FUNC void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd);
30LJ_FUNC int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd); 30LJ_FUNC int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd);
31LJ_FUNC int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd); 31LJ_FUNC int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd);
32LJ_FUNC int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd); 32LJ_FUNC int recff_bit64_shift(jit_State *J, TRef *rb, TRef *rc,
33 TValue *rbv, TValue *rcv, IROp op);
33LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr); 34LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr);
35LJ_FUNC TRef recff_bit64_bitop(jit_State *J, TRef rb, TRef rc,
36 TValue *rbv, TValue *rcv, IROp op);
34 37
35LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); 38LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
36LJ_FUNC TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o); 39LJ_FUNC TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o);
diff --git a/src/lj_dispatch.h b/src/lj_dispatch.h
index 9baf762b2..755590e67 100644
--- a/src/lj_dispatch.h
+++ b/src/lj_dispatch.h
@@ -49,6 +49,7 @@ extern double __divdf3(double a, double b);
49 _(lj_dispatch_profile) _(lj_err_throw) \ 49 _(lj_dispatch_profile) _(lj_err_throw) \
50 _(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \ 50 _(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \
51 _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \ 51 _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \
52 _(lj_meta_bitop) \
52 _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \ 53 _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \
53 _(lj_meta_for) _(lj_meta_istype) _(lj_meta_len) _(lj_meta_tget) \ 54 _(lj_meta_for) _(lj_meta_istype) _(lj_meta_len) _(lj_meta_tget) \
54 _(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_number) \ 55 _(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_number) \
diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h
index daf7fb6bf..ad8581c99 100644
--- a/src/lj_errmsg.h
+++ b/src/lj_errmsg.h
@@ -140,9 +140,13 @@ ERRDEF(XDOTS, "cannot use " LUA_QL("...") " outside a vararg function")
140ERRDEF(XSYNTAX, "syntax error") 140ERRDEF(XSYNTAX, "syntax error")
141ERRDEF(XFOR, LUA_QL("=") " or " LUA_QL("in") " expected") 141ERRDEF(XFOR, LUA_QL("=") " or " LUA_QL("in") " expected")
142ERRDEF(XBREAK, "no loop to break") 142ERRDEF(XBREAK, "no loop to break")
143ERRDEF(XCONT, "no loop to continue")
143ERRDEF(XLUNDEF, "undefined label " LUA_QS) 144ERRDEF(XLUNDEF, "undefined label " LUA_QS)
144ERRDEF(XLDUP, "duplicate label " LUA_QS) 145ERRDEF(XLDUP, "duplicate label " LUA_QS)
145ERRDEF(XGSCOPE, "<goto %s> jumps into the scope of local " LUA_QS) 146ERRDEF(XGSCOPE, "<goto %s> jumps into the scope of local " LUA_QS)
147ERRDEF(XCSCOPE, "<continue> jumps into the scope of local " LUA_QS)
148ERRDEF(XCONSTA, "attempt to assign to const variable " LUA_QS)
149ERRDEF(XCONSTR, "attempt to re-declare const variable " LUA_QS)
146 150
147/* Bytecode reader errors. */ 151/* Bytecode reader errors. */
148ERRDEF(BCFMT, "cannot load incompatible bytecode") 152ERRDEF(BCFMT, "cannot load incompatible bytecode")
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c
index edbf13cc2..4349f748f 100644
--- a/src/lj_ffrecord.c
+++ b/src/lj_ffrecord.c
@@ -745,7 +745,7 @@ static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd)
745static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd) 745static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd)
746{ 746{
747#if LJ_HASFFI 747#if LJ_HASFFI
748 if (recff_bit64_shift(J, rd)) 748 if (recff_bit64_shift(J, &J->base[0], &J->base[1], &rd->argv[0], &rd->argv[1], rd->data))
749 return; 749 return;
750#endif 750#endif
751 { 751 {
diff --git a/src/lj_ir.h b/src/lj_ir.h
index b9f5e2c13..879196a52 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -53,7 +53,7 @@
53 _(KINT64, N , cst, ___) \ 53 _(KINT64, N , cst, ___) \
54 _(KSLOT, N , ref, lit) \ 54 _(KSLOT, N , ref, lit) \
55 \ 55 \
56 /* Bit ops. */ \ 56 /* Bit ops. ORDER BIT */ \
57 _(BNOT, N , ref, ___) \ 57 _(BNOT, N , ref, ___) \
58 _(BSWAP, N , ref, ___) \ 58 _(BSWAP, N , ref, ___) \
59 _(BAND, C , ref, ref) \ 59 _(BAND, C , ref, ref) \
diff --git a/src/lj_lex.c b/src/lj_lex.c
index a585cb585..4bbe18359 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -97,12 +97,18 @@ static void lex_number(LexState *ls, TValue *tv)
97 StrScanFmt fmt; 97 StrScanFmt fmt;
98 LexChar c, xp = 'e'; 98 LexChar c, xp = 'e';
99 lj_assertLS(lj_char_isdigit(ls->c), "bad usage"); 99 lj_assertLS(lj_char_isdigit(ls->c), "bad usage");
100 if ((c = ls->c) == '0' && (lex_savenext(ls) | 0x20) == 'x') 100 if ((c = ls->c) == '0') {
101 xp = 'p'; 101 lex_save(ls, c);
102 do { c = lex_next(ls); } while (c == '_');
103 if ((c | 0x20) == 'x') xp = 'p';
104 }
102 while (lj_char_isident(ls->c) || ls->c == '.' || 105 while (lj_char_isident(ls->c) || ls->c == '.' ||
103 ((ls->c == '-' || ls->c == '+') && (c | 0x20) == xp)) { 106 ((ls->c == '-' || ls->c == '+') && (c | 0x20) == xp)) {
104 c = ls->c; 107 if (LJ_LIKELY(ls->c != '_')) {
105 lex_savenext(ls); 108 c = ls->c;
109 lex_save(ls, ls->c);
110 }
111 lex_next(ls);
106 } 112 }
107 lex_save(ls, '\0'); 113 lex_save(ls, '\0');
108 fmt = lj_strscan_scan((const uint8_t *)ls->sb.b, sbuflen(&ls->sb)-1, tv, 114 fmt = lj_strscan_scan((const uint8_t *)ls->sb.b, sbuflen(&ls->sb)-1, tv,
@@ -321,7 +327,9 @@ static LexToken lex_scan(LexState *ls, TValue *tv)
321 continue; 327 continue;
322 case '-': 328 case '-':
323 lex_next(ls); 329 lex_next(ls);
324 if (ls->c != '-') return '-'; 330 if (ls->c != '-') {
331 if (ls->c != '>') return '-'; else { lex_next(ls); return TK_arrow; }
332 }
325 lex_next(ls); 333 lex_next(ls);
326 if (ls->c == '[') { /* Long comment "--[=*[...]=*]". */ 334 if (ls->c == '[') { /* Long comment "--[=*[...]=*]". */
327 int sep = lex_skipeq(ls); 335 int sep = lex_skipeq(ls);
@@ -353,16 +361,41 @@ static LexToken lex_scan(LexState *ls, TValue *tv)
353 if (ls->c != '=') return '='; else { lex_next(ls); return TK_eq; } 361 if (ls->c != '=') return '='; else { lex_next(ls); return TK_eq; }
354 case '<': 362 case '<':
355 lex_next(ls); 363 lex_next(ls);
356 if (ls->c != '=') return '<'; else { lex_next(ls); return TK_le; } 364 if (ls->c == '=') { lex_next(ls); return TK_le; }
365 if (ls->c == '<') { lex_next(ls); return TK_shl; }
366 return '<';
357 case '>': 367 case '>':
358 lex_next(ls); 368 lex_next(ls);
359 if (ls->c != '=') return '>'; else { lex_next(ls); return TK_ge; } 369 if (ls->c == '=') { lex_next(ls); return TK_ge; }
370 if (ls->c == '>') { lex_next(ls); return TK_shr; }
371 return '>';
360 case '~': 372 case '~':
361 lex_next(ls); 373 lex_next(ls);
362 if (ls->c != '=') return '~'; else { lex_next(ls); return TK_ne; } 374 if (ls->c == '=') { lex_next(ls); return TK_ne; }
375 if (ls->c == '>') {
376 lex_next(ls);
377 if (ls->c != '>') lj_lex_error(ls, '~', LJ_ERR_XSYMBOL);
378 lex_next(ls);
379 return TK_sar;
380 }
381 return '~';
382 case '!':
383 lex_next(ls);
384 if (ls->c != '=') return '!'; else { lex_next(ls); return TK_ne_; }
363 case ':': 385 case ':':
364 lex_next(ls); 386 lex_next(ls);
365 if (ls->c != ':') return ':'; else { lex_next(ls); return TK_label; } 387 if (ls->c != ':') return ':'; else { lex_next(ls); return TK_label; }
388 case '?':
389 lex_next(ls);
390 if (ls->c == '.') { lex_next(ls); return TK_nav; }
391 if (ls->c == '?') { lex_next(ls); return TK_coal; }
392 return '?';
393 case '&':
394 lex_next(ls);
395 if (ls->c != '&') return '&'; else { lex_next(ls); return TK_and_; }
396 case '|':
397 lex_next(ls);
398 if (ls->c != '|') return '|'; else { lex_next(ls); return TK_or_; }
366 case '"': 399 case '"':
367 case '\'': 400 case '\'':
368 lex_string(ls, tv); 401 lex_string(ls, tv);
diff --git a/src/lj_lex.h b/src/lj_lex.h
index 8d5c9a336..e5b78337c 100644
--- a/src/lj_lex.h
+++ b/src/lj_lex.h
@@ -13,10 +13,12 @@
13 13
14/* Lua lexer tokens. */ 14/* Lua lexer tokens. */
15#define TKDEF(_, __) \ 15#define TKDEF(_, __) \
16 _(and) _(break) _(do) _(else) _(elseif) _(end) _(false) \ 16 _(and) _(break) _(const) _(continue) _(do) _(else) _(elseif) _(end) _(false) \
17 _(for) _(function) _(goto) _(if) _(in) _(local) _(nil) _(not) _(or) \ 17 _(for) _(function) _(goto) _(if) _(in) _(local) _(nil) _(not) _(or) \
18 _(repeat) _(return) _(then) _(true) _(until) _(while) \ 18 _(repeat) _(return) _(then) _(true) _(until) _(while) \
19 __(concat, ..) __(dots, ...) __(eq, ==) __(ge, >=) __(le, <=) __(ne, ~=) \ 19 __(concat, ..) __(dots, ...) __(eq, ==) __(ge, >=) __(le, <=) __(ne, ~=) \
20 __(nav, ?.) __(coal, \?\?) __(shl, <<) __(shr, >>) __(sar, ~>>) \
21 __(and_, &&) __(or_, ||) __(ne_, !=) __(arrow, ->) \
20 __(label, ::) __(number, <number>) __(name, <name>) __(string, <string>) \ 22 __(label, ::) __(number, <number>) __(name, <name>) __(string, <string>) \
21 __(eof, <eof>) 23 __(eof, <eof>)
22 24
@@ -39,6 +41,12 @@ typedef struct BCInsLine {
39 BCLine line; /* Line number for this bytecode. */ 41 BCLine line; /* Line number for this bytecode. */
40} BCInsLine; 42} BCInsLine;
41 43
44/* Index into variable stack. */
45typedef uint16_t VarIndex;
46
47#define LJ_VINDEX_HSIZE 32 /* Hash table size. Must be a power of 2. */
48#define LJ_VINDEX_MASK (LJ_VINDEX_HSIZE-1)
49
42/* Info for local variables. Only used during bytecode generation. */ 50/* Info for local variables. Only used during bytecode generation. */
43typedef struct VarInfo { 51typedef struct VarInfo {
44 GCRef name; /* Local variable name or goto/label name. */ 52 GCRef name; /* Local variable name or goto/label name. */
@@ -46,6 +54,7 @@ typedef struct VarInfo {
46 BCPos endpc; /* First point where the local variable is dead. */ 54 BCPos endpc; /* First point where the local variable is dead. */
47 uint8_t slot; /* Variable slot. */ 55 uint8_t slot; /* Variable slot. */
48 uint8_t info; /* Variable/goto/label info. */ 56 uint8_t info; /* Variable/goto/label info. */
57 VarIndex prev; /* Previous entry in variable hash chain. */
49} VarInfo; 58} VarInfo;
50 59
51/* Lua lexer state. */ 60/* Lua lexer state. */
@@ -75,6 +84,7 @@ typedef struct LexState {
75 uint32_t level; /* Syntactical nesting level. */ 84 uint32_t level; /* Syntactical nesting level. */
76 int endmark; /* Trust bytecode end marker, even if not at EOF. */ 85 int endmark; /* Trust bytecode end marker, even if not at EOF. */
77 int fr2; /* Generate bytecode for LJ_FR2 mode. */ 86 int fr2; /* Generate bytecode for LJ_FR2 mode. */
87 VarIndex vhash[LJ_VINDEX_HSIZE]; /* Variable hash chain anchors. */
78} LexState; 88} LexState;
79 89
80LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls); 90LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
diff --git a/src/lj_meta.c b/src/lj_meta.c
index 1e7262a43..ddb37a1a3 100644
--- a/src/lj_meta.c
+++ b/src/lj_meta.c
@@ -22,6 +22,11 @@
22#include "lj_strscan.h" 22#include "lj_strscan.h"
23#include "lj_strfmt.h" 23#include "lj_strfmt.h"
24#include "lj_lib.h" 24#include "lj_lib.h"
25#if LJ_HASFFI
26#include "lj_ctype.h"
27#include "lj_cdata.h"
28#include "lj_carith.h"
29#endif
25 30
26/* -- Metamethod handling ------------------------------------------------- */ 31/* -- Metamethod handling ------------------------------------------------- */
27 32
@@ -234,6 +239,76 @@ TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc,
234 } 239 }
235} 240}
236 241
242/* Helper for bit operators. No bitop metamethods in v2.1. */
243void lj_meta_bitop(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc, BCReg op)
244{
245#if LJ_HASFFI
246 CTypeID id = 0, id_ignore = 0;
247 uint64_t b = lj_carith_checkbit64(L, rb, &id);
248 uint64_t c = lj_carith_checkbit64(L, rc, op >= BC_BSHL ? &id_ignore : &id);
249 if (id) {
250 if (tvisnum(rb)) {
251 b = id == CTID_UINT64 ? lj_num2u64(numV(rb)) : lj_num2i64(numV(rb));
252 }
253 if (tvisnum(rc)) {
254 c = id == CTID_UINT64 ? lj_num2u64(numV(rc)) : lj_num2i64(numV(rc));
255 }
256 }
257 switch (op) {
258 case BC_BNOT: b = ~b; break;
259 case BC_BAND: b &= c; break;
260 case BC_BOR: b |= c; break;
261 case BC_BXOR: b ^= c; break;
262 default:
263 if (id) {
264 b = lj_carith_shift64(b, (int32_t)c, op-BC_BSHL);
265 } else if (op == BC_BSHL) {
266 b = (uint64_t)((uint32_t)b << ((uint32_t)c & 31));
267 } else if (op == BC_BSHR) {
268 b = (uint64_t)((uint32_t)b >> ((uint32_t)c & 31));
269 } else {
270 lj_assertL(op == BC_BSAR, "bad bytecode op %d", op);
271 b = (uint64_t)(uint32_t)((int32_t)b >> ((uint32_t)c & 31));
272 }
273 break;
274 }
275 if (id) {
276 GCcdata *cd = lj_cdata_new_(L, id, 8);
277 *(uint64_t *)cdataptr(cd) = b;
278 setcdataV(L, ra, cd);
279 } else {
280 setintV(ra, (int32_t)b);
281 }
282#else
283#if LJ_DUALNUM
284 uint32_t b = 0, c = 0;
285 if (tvisint(rb)) b = (uint32_t)intV(rb);
286 else if (tvisnum(rb)) b = (uint32_t)lj_num2bit(numV(rb));
287 else goto err;
288 if (tvisint(rc)) c = (uint32_t)intV(rc);
289 else if (tvisnum(rc)) c = (uint32_t)lj_num2bit(numV(rc));
290 else goto err;
291 switch (op) {
292 case BC_BNOT: b = ~b; break;
293 case BC_BAND: b &= c; break;
294 case BC_BOR: b |= c; break;
295 case BC_BXOR: b ^= c; break;
296 case BC_BSHL: b <<= (c & 31); break;
297 case BC_BSHR: b >>= (c & 31); break;
298 case BC_BSAR: b = (uint32_t)((int32_t)b >> (c & 31)); break;
299 default:
300 lj_assertL(0, "bad bytecode op %d", op);
301 break;
302 }
303 setintV(ra, (int32_t)b);
304 return;
305err:
306#endif
307 UNUSED(ra); UNUSED(op);
308 lj_err_optype(L, tvisnumber(rb) ? rc : rb, LJ_ERR_OPARITH);
309#endif
310}
311
237/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */ 312/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
238TValue *lj_meta_cat(lua_State *L, TValue *top, int left) 313TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
239{ 314{
diff --git a/src/lj_meta.h b/src/lj_meta.h
index 3d6a71c05..28e6c8bb1 100644
--- a/src/lj_meta.h
+++ b/src/lj_meta.h
@@ -26,6 +26,8 @@ LJ_FUNCA cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k);
26LJ_FUNCA TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k); 26LJ_FUNCA TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k);
27LJ_FUNCA TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb, 27LJ_FUNCA TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb,
28 cTValue *rc, BCReg op); 28 cTValue *rc, BCReg op);
29LJ_FUNCA void lj_meta_bitop(lua_State *L, TValue *ra, cTValue *rb,
30 cTValue *rc, BCReg op);
29LJ_FUNCA TValue *lj_meta_cat(lua_State *L, TValue *top, int left); 31LJ_FUNCA TValue *lj_meta_cat(lua_State *L, TValue *top, int left);
30LJ_FUNCA TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o); 32LJ_FUNCA TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o);
31LJ_FUNCA TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne); 33LJ_FUNCA TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne);
diff --git a/src/lj_obj.h b/src/lj_obj.h
index f380c78fc..96dc1e0d0 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -401,6 +401,7 @@ typedef struct GCproto {
401#define PROTO_FFI 0x04 /* Uses BC_KCDATA for FFI datatypes. */ 401#define PROTO_FFI 0x04 /* Uses BC_KCDATA for FFI datatypes. */
402#define PROTO_NOJIT 0x08 /* JIT disabled for this function. */ 402#define PROTO_NOJIT 0x08 /* JIT disabled for this function. */
403#define PROTO_ILOOP 0x10 /* Patched bytecode with ILOOP etc. */ 403#define PROTO_ILOOP 0x10 /* Patched bytecode with ILOOP etc. */
404#define PROTO_BITOP 0x80 /* Uses bit operator bytecodes. */
404/* Only used during parsing. */ 405/* Only used during parsing. */
405#define PROTO_HAS_RETURN 0x20 /* Already emitted a return. */ 406#define PROTO_HAS_RETURN 0x20 /* Already emitted a return. */
406#define PROTO_FIXUP_RETURN 0x40 /* Need to fixup emitted returns. */ 407#define PROTO_FIXUP_RETURN 0x40 /* Need to fixup emitted returns. */
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 7fc838373..cc2b9098c 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -382,8 +382,8 @@ static uint64_t kfold_int64arith(jit_State *J, uint64_t k1, uint64_t k2,
382 case IR_BSAR: k1 = (uint64_t)((int64_t)k1 >> (k2 & 63)); break; 382 case IR_BSAR: k1 = (uint64_t)((int64_t)k1 >> (k2 & 63)); break;
383 case IR_BROL: k1 = lj_rol(k1, (k2 & 63)); break; 383 case IR_BROL: k1 = lj_rol(k1, (k2 & 63)); break;
384 case IR_BROR: k1 = lj_ror(k1, (k2 & 63)); break; 384 case IR_BROR: k1 = lj_ror(k1, (k2 & 63)); break;
385 default: lj_assertJ(0, "bad IR op %d", op); break;
386#endif 385#endif
386 default: lj_assertJ(0, "bad IR op %d", op); break;
387 } 387 }
388 return k1; 388 return k1;
389} 389}
diff --git a/src/lj_parse.c b/src/lj_parse.c
index 66e5a0341..00a64382c 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -49,6 +49,7 @@ typedef enum {
49 VRELOCABLE, /* info = instruction PC */ 49 VRELOCABLE, /* info = instruction PC */
50 VNONRELOC, /* info = result register */ 50 VNONRELOC, /* info = result register */
51 VCALL, /* info = instruction PC, aux = base */ 51 VCALL, /* info = instruction PC, aux = base */
52 VCALLNAV, /* info = instruction PC, aux = base */
52 VVOID 53 VVOID
53} ExpKind; 54} ExpKind;
54 55
@@ -79,6 +80,18 @@ typedef struct ExpDesc {
79#define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval) 80#define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval)
80#define expr_numberV(e) numberVnum(expr_numtv((e))) 81#define expr_numberV(e) numberVnum(expr_numtv((e)))
81 82
83/* Expression flags. */
84#define EXPR_F_NORES 0x01 /* Result will not be used. */
85#define EXPR_F_NOCOLON 0x02 /* Disallow colon for method call.*/
86#define EXPR_F_NONAV 0x04 /* Disallow safe navigation. */
87#define EXPR_F_RET1 0x08 /* Return a single expr. */
88
89static LJ_AINLINE int32_t expr_bitV(ExpDesc *e)
90{
91 TValue *o = expr_numtv(e);
92 return tvisint(o) ? intV(o) : lj_num2bit(numV(o));
93}
94
82/* Initialize expression. */ 95/* Initialize expression. */
83static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) 96static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info)
84{ 97{
@@ -107,17 +120,22 @@ typedef struct FuncScope {
107#define FSCOPE_GOLA 0x04 /* Goto or label used in scope. */ 120#define FSCOPE_GOLA 0x04 /* Goto or label used in scope. */
108#define FSCOPE_UPVAL 0x08 /* Upvalue in scope. */ 121#define FSCOPE_UPVAL 0x08 /* Upvalue in scope. */
109#define FSCOPE_NOCLOSE 0x10 /* Do not close upvalues. */ 122#define FSCOPE_NOCLOSE 0x10 /* Do not close upvalues. */
123#define FSCOPE_CONT 0x20 /* Continue used in scope. */
110 124
111#define NAME_BREAK ((GCstr *)(uintptr_t)1) 125#define NAME_BREAK ((GCstr *)(uintptr_t)1)
126#define NAME_CONT ((GCstr *)(uintptr_t)2)
112 127
113/* Index into variable stack. */ 128/* Index into variable stack. See VarIndex in lj_lex.h. */
114typedef uint16_t VarIndex; 129#define VINDEX_NONE 0xffff
115#define LJ_MAX_VSTACK (65536 - LJ_MAX_UPVAL) 130#define LJ_MAX_VSTACK (65536 - LJ_MAX_UPVAL)
116 131
132#define LJ_HASH_VSTACK 0x20 /* Must be a power of 2. */
133
117/* Variable/goto/label info. */ 134/* Variable/goto/label info. */
118#define VSTACK_VAR_RW 0x01 /* R/W variable. */ 135#define VSTACK_VAR_RW 0x01 /* R/W variable. */
119#define VSTACK_GOTO 0x02 /* Pending goto. */ 136#define VSTACK_GOTO 0x02 /* Pending goto. */
120#define VSTACK_LABEL 0x04 /* Label. */ 137#define VSTACK_LABEL 0x04 /* Label. */
138#define VSTACK_CONST 0x08 /* Constant variable. */
121 139
122/* Per-function state. */ 140/* Per-function state. */
123typedef struct FuncState { 141typedef struct FuncState {
@@ -148,10 +166,11 @@ typedef struct FuncState {
148/* Binary and unary operators. ORDER OPR */ 166/* Binary and unary operators. ORDER OPR */
149typedef enum BinOpr { 167typedef enum BinOpr {
150 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, /* ORDER ARITH */ 168 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, /* ORDER ARITH */
169 OPR_BAND, OPR_BOR, OPR_BXOR, OPR_BSHL, OPR_BSHR, OPR_BSAR, /* ORDER BIT */
151 OPR_CONCAT, 170 OPR_CONCAT,
152 OPR_NE, OPR_EQ, 171 OPR_NE, OPR_EQ,
153 OPR_LT, OPR_GE, OPR_LE, OPR_GT, 172 OPR_LT, OPR_GE, OPR_LE, OPR_GT,
154 OPR_AND, OPR_OR, 173 OPR_AND, OPR_OR, OPR_COAL,
155 OPR_NOBINOPR 174 OPR_NOBINOPR
156} BinOpr; 175} BinOpr;
157 176
@@ -458,7 +477,7 @@ static void expr_discharge(FuncState *fs, ExpDesc *e)
458 ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc); 477 ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc);
459 } 478 }
460 bcreg_free(fs, e->u.s.info); 479 bcreg_free(fs, e->u.s.info);
461 } else if (e->k == VCALL) { 480 } else if (e->k == VCALL || e->k == VCALLNAV) {
462 e->u.s.info = e->u.s.aux; 481 e->u.s.info = e->u.s.aux;
463 e->k = VNONRELOC; 482 e->k = VNONRELOC;
464 return; 483 return;
@@ -623,11 +642,13 @@ static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e)
623{ 642{
624 BCIns ins; 643 BCIns ins;
625 if (var->k == VLOCAL) { 644 if (var->k == VLOCAL) {
645 lj_assertFS(!(fs->ls->vstack[var->u.s.aux].info & VSTACK_CONST), "unchecked const assignment");
626 fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW; 646 fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
627 expr_free(fs, e); 647 expr_free(fs, e);
628 expr_toreg(fs, e, var->u.s.info); 648 expr_toreg(fs, e, var->u.s.info);
629 return; 649 return;
630 } else if (var->k == VUPVAL) { 650 } else if (var->k == VUPVAL) {
651 lj_assertFS(!(fs->ls->vstack[var->u.s.aux].info & VSTACK_CONST), "unchecked const assignment");
631 fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW; 652 fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
632 expr_toval(fs, e); 653 expr_toval(fs, e);
633 if (e->k <= VKTRUE) 654 if (e->k <= VKTRUE)
@@ -793,17 +814,39 @@ static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
793 return 1; 814 return 1;
794} 815}
795 816
817/* Try constant-folding of bit operators. */
818static int foldbitop(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
819{
820 if (expr_isnumk_nojump(e1) && expr_isnumk_nojump(e2)) {
821 int32_t k1 = expr_bitV(e1), k2 = expr_bitV(e2);
822 switch (opr) {
823 case OPR_BAND: k1 &= k2; break;
824 case OPR_BOR: k1 |= k2; break;
825 case OPR_BXOR: k1 ^= k2; break;
826 case OPR_BSHL: k1 <<= (k2 & 31); break;
827 case OPR_BSHR: k1 = (int32_t)((uint32_t)k1 >> (k2 & 31)); break;
828 case OPR_BSAR: k1 >>= (k2 & 31); break;
829 default: lj_assertX(0, "bad OPR %d", opr); break;
830 }
831 setintV(&e1->u.nval, k1);
832 return 1;
833 }
834 return 0;
835}
836
796/* Emit arithmetic operator. */ 837/* Emit arithmetic operator. */
797static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) 838static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
798{ 839{
799 BCReg rb, rc, t; 840 BCReg rb, rc, t;
800 uint32_t op; 841 uint32_t op;
801 if (foldarith(opr, e1, e2))
802 return;
803 if (opr == OPR_POW) { 842 if (opr == OPR_POW) {
804 op = BC_POW; 843 op = BC_POW;
805 rc = expr_toanyreg(fs, e2); 844 rc = expr_toanyreg(fs, e2);
806 rb = expr_toanyreg(fs, e1); 845 rb = expr_toanyreg(fs, e1);
846 } else if (opr >= OPR_BAND) {
847 op = opr-OPR_BAND+BC_BAND;
848 rc = expr_toanyreg(fs, e2);
849 rb = expr_toanyreg(fs, e1);
807 } else { 850 } else {
808 op = opr-OPR_ADD+BC_ADDVV; 851 op = opr-OPR_ADD+BC_ADDVV;
809 /* Must discharge 2nd operand first since VINDEXED might free regs. */ 852 /* Must discharge 2nd operand first since VINDEXED might free regs. */
@@ -887,6 +930,13 @@ static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e)
887 bcemit_branch_t(fs, e); 930 bcemit_branch_t(fs, e);
888 } else if (op == OPR_OR) { 931 } else if (op == OPR_OR) {
889 bcemit_branch_f(fs, e); 932 bcemit_branch_f(fs, e);
933 } else if (op == OPR_COAL) {
934 BCReg reg;
935 expr_tonextreg(fs, e);
936 reg = e->u.s.info;
937 bcemit_INS(fs, BCINS_AD(BC_ISNEP, reg, VKNIL));
938 e->u.s.aux = bcemit_jmp(fs);
939 bcreg_free(fs, reg);
890 } else if (op == OPR_CONCAT) { 940 } else if (op == OPR_CONCAT) {
891 expr_tonextreg(fs, e); 941 expr_tonextreg(fs, e);
892 } else if (op == OPR_EQ || op == OPR_NE) { 942 } else if (op == OPR_EQ || op == OPR_NE) {
@@ -900,7 +950,12 @@ static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e)
900static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2) 950static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2)
901{ 951{
902 if (op <= OPR_POW) { 952 if (op <= OPR_POW) {
903 bcemit_arith(fs, op, e1, e2); 953 if (!foldarith(op, e1, e2)) bcemit_arith(fs, op, e1, e2);
954 } else if (op <= OPR_BSAR) {
955 if (!foldbitop(op, e1, e2)) {
956 fs->flags |= PROTO_BITOP;
957 bcemit_arith(fs, op, e1, e2);
958 }
904 } else if (op == OPR_AND) { 959 } else if (op == OPR_AND) {
905 lj_assertFS(e1->t == NO_JMP, "jump list not closed"); 960 lj_assertFS(e1->t == NO_JMP, "jump list not closed");
906 expr_discharge(fs, e2); 961 expr_discharge(fs, e2);
@@ -911,6 +966,9 @@ static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2)
911 expr_discharge(fs, e2); 966 expr_discharge(fs, e2);
912 jmp_append(fs, &e2->t, e1->t); 967 jmp_append(fs, &e2->t, e1->t);
913 *e1 = *e2; 968 *e1 = *e2;
969 } else if (op == OPR_COAL) {
970 expr_tonextreg(fs, e2);
971 jmp_tohere(fs, e1->u.s.aux);
914 } else if (op == OPR_CONCAT) { 972 } else if (op == OPR_CONCAT) {
915 expr_toval(fs, e2); 973 expr_toval(fs, e2);
916 if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) { 974 if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) {
@@ -961,34 +1019,41 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
961 lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k); 1019 lj_assertFS(e->k == VNONRELOC, "bad expr type %d", e->k);
962 } 1020 }
963 } else { 1021 } else {
964 lj_assertFS(op == BC_UNM || op == BC_LEN, "bad unop %d", op); 1022 lj_assertFS(op == BC_UNM || op == BC_LEN || op == BC_BNOT, "bad unop %d", op);
965 if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */ 1023 if (!expr_hasjump(e)) {
1024 if (op == BC_UNM) { /* Constant-fold negations. */
966#if LJ_HASFFI 1025#if LJ_HASFFI
967 if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ 1026 if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */
968 GCcdata *cd = cdataV(&e->u.nval); 1027 GCcdata *cd = cdataV(&e->u.nval);
969 uint64_t *p = (uint64_t *)cdataptr(cd); 1028 uint64_t *p = (uint64_t *)cdataptr(cd);
970 if (cd->ctypeid == CTID_COMPLEX_DOUBLE) 1029 if (cd->ctypeid == CTID_COMPLEX_DOUBLE)
971 p[1] ^= U64x(80000000,00000000); 1030 p[1] ^= U64x(80000000,00000000);
972 else
973 *p = ~*p+1u;
974 return;
975 } else
976#endif
977 if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */
978 TValue *o = expr_numtv(e);
979 if (tvisint(o)) {
980 int32_t k = intV(o), negk = (int32_t)(~(uint32_t)k+1u);
981 if (k == negk)
982 setnumV(o, -(lua_Number)k);
983 else 1031 else
984 setintV(o, negk); 1032 *p = ~*p+1u;
985 return;
986 } else {
987 o->u64 ^= U64x(80000000,00000000);
988 return; 1033 return;
1034 } else
1035#endif
1036 if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */
1037 TValue *o = expr_numtv(e);
1038 if (tvisint(o)) {
1039 int32_t k = intV(o), negk = (int32_t)(~(uint32_t)k+1u);
1040 if (k == negk)
1041 setnumV(o, -(lua_Number)k);
1042 else
1043 setintV(o, negk);
1044 return;
1045 } else {
1046 o->u64 ^= U64x(80000000,00000000);
1047 return;
1048 }
989 } 1049 }
1050 } else if (op == BC_BNOT && expr_isnumk(e)) {
1051 /* Constant-fold bitwise not. */
1052 setintV(&e->u.nval, (int32_t)~(uint32_t)expr_bitV(e));
1053 return;
990 } 1054 }
991 } 1055 }
1056 if (op == BC_BNOT) fs->flags |= PROTO_BITOP;
992 expr_toanyreg(fs, e); 1057 expr_toanyreg(fs, e);
993 } 1058 }
994 expr_free(fs, e); 1059 expr_free(fs, e);
@@ -1030,11 +1095,20 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line)
1030 } 1095 }
1031} 1096}
1032 1097
1098/* Check for a name, including soft keywords. */
1099static LJ_AINLINE int lex_isname(LexToken tok)
1100{
1101 return (tok == TK_name ||
1102 (!LJ_52 && tok == TK_goto) ||
1103 tok == TK_continue ||
1104 tok == TK_const);
1105}
1106
1033/* Check for string token. */ 1107/* Check for string token. */
1034static GCstr *lex_str(LexState *ls) 1108static GCstr *lex_str(LexState *ls)
1035{ 1109{
1036 GCstr *s; 1110 GCstr *s;
1037 if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto)) 1111 if (!lex_isname(ls->tok))
1038 err_token(ls, TK_name); 1112 err_token(ls, TK_name);
1039 s = strV(&ls->tokval); 1113 s = strV(&ls->tokval);
1040 lj_lex_next(ls); 1114 lj_lex_next(ls);
@@ -1045,11 +1119,31 @@ static GCstr *lex_str(LexState *ls)
1045 1119
1046#define var_get(ls, fs, i) ((ls)->vstack[(fs)->varmap[(i)]]) 1120#define var_get(ls, fs, i) ((ls)->vstack[(fs)->varmap[(i)]])
1047 1121
1122typedef intptr_t VarHash; /* For performance reasons. */
1123
1124/* Hash of a variable name. */
1125static LJ_AINLINE VarHash var_hash(GCstr *name)
1126{
1127 if ((uintptr_t)name < VARNAME__MAX)
1128 return -1;
1129 else
1130 return (name->sid & LJ_VINDEX_MASK); /* Immutable id, not name->hash! */
1131}
1132
1048/* Define a new local variable. */ 1133/* Define a new local variable. */
1049static void var_new(LexState *ls, BCReg n, GCstr *name) 1134static MSize var_new(LexState *ls, BCReg n, GCstr *name)
1050{ 1135{
1051 FuncState *fs = ls->fs; 1136 FuncState *fs = ls->fs;
1052 MSize vtop = ls->vtop; 1137 MSize vtop = ls->vtop;
1138 if ((uintptr_t)name >= VARNAME__MAX) { /* Check for const re-declaration. */
1139 MSize vidx = ls->vhash[var_hash(name)];
1140 while (vidx != VINDEX_NONE) {
1141 VarInfo *v = &ls->vstack[vidx];
1142 if (strref(v->name) == name && (v->info & VSTACK_CONST))
1143 lj_lex_error(ls, 0, LJ_ERR_XCONSTR, strdata(name));
1144 vidx = v->prev;
1145 }
1146 }
1053 checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables"); 1147 checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables");
1054 if (LJ_UNLIKELY(vtop >= ls->sizevstack)) { 1148 if (LJ_UNLIKELY(vtop >= ls->sizevstack)) {
1055 if (ls->sizevstack >= LJ_MAX_VSTACK) 1149 if (ls->sizevstack >= LJ_MAX_VSTACK)
@@ -1061,8 +1155,11 @@ static void var_new(LexState *ls, BCReg n, GCstr *name)
1061 "unanchored variable name"); 1155 "unanchored variable name");
1062 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ 1156 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1063 setgcref(ls->vstack[vtop].name, obj2gco(name)); 1157 setgcref(ls->vstack[vtop].name, obj2gco(name));
1158 ls->vstack[vtop].info = 0;
1159 /* The other VarInfo fields are filled in by var_add and var_remove. */
1064 fs->varmap[fs->nactvar+n] = (uint16_t)vtop; 1160 fs->varmap[fs->nactvar+n] = (uint16_t)vtop;
1065 ls->vtop = vtop+1; 1161 ls->vtop = vtop+1;
1162 return vtop;
1066} 1163}
1067 1164
1068#define var_new_lit(ls, n, v) \ 1165#define var_new_lit(ls, n, v) \
@@ -1077,10 +1174,15 @@ static void var_add(LexState *ls, BCReg nvars)
1077 FuncState *fs = ls->fs; 1174 FuncState *fs = ls->fs;
1078 BCReg nactvar = fs->nactvar; 1175 BCReg nactvar = fs->nactvar;
1079 while (nvars--) { 1176 while (nvars--) {
1080 VarInfo *v = &var_get(ls, fs, nactvar); 1177 intptr_t vidx = fs->varmap[nactvar];
1178 VarInfo *v = &ls->vstack[vidx];
1179 VarHash hash = var_hash(strref(v->name));
1081 v->startpc = fs->pc; 1180 v->startpc = fs->pc;
1082 v->slot = nactvar++; 1181 v->slot = nactvar++;
1083 v->info = 0; 1182 if (hash != -1) {
1183 v->prev = ls->vhash[hash];
1184 ls->vhash[hash] = vidx;
1185 }
1084 } 1186 }
1085 fs->nactvar = nactvar; 1187 fs->nactvar = nactvar;
1086} 1188}
@@ -1089,70 +1191,86 @@ static void var_add(LexState *ls, BCReg nvars)
1089static void var_remove(LexState *ls, BCReg tolevel) 1191static void var_remove(LexState *ls, BCReg tolevel)
1090{ 1192{
1091 FuncState *fs = ls->fs; 1193 FuncState *fs = ls->fs;
1092 while (fs->nactvar > tolevel) 1194 while (fs->nactvar > tolevel) {
1093 var_get(ls, fs, --fs->nactvar).endpc = fs->pc; 1195 VarInfo *v = &var_get(ls, fs, --fs->nactvar);
1094} 1196 VarHash hash = var_hash(strref(v->name));
1095 1197 v->endpc = fs->pc;
1096/* Lookup local variable name. */ 1198 if (hash != -1) {
1097static BCReg var_lookup_local(FuncState *fs, GCstr *n) 1199 ls->vhash[hash] = v->prev;
1098{ 1200 }
1099 int i;
1100 for (i = fs->nactvar-1; i >= 0; i--) {
1101 if (n == strref(var_get(fs->ls, fs, i).name))
1102 return (BCReg)i;
1103 } 1201 }
1104 return (BCReg)-1; /* Not found. */
1105}
1106
1107/* Lookup or add upvalue index. */
1108static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e)
1109{
1110 MSize i, n = fs->nuv;
1111 for (i = 0; i < n; i++)
1112 if (fs->uvmap[i] == vidx)
1113 return i; /* Already exists. */
1114 /* Otherwise create a new one. */
1115 checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues");
1116 lj_assertFS(e->k == VLOCAL || e->k == VUPVAL, "bad expr type %d", e->k);
1117 fs->uvmap[n] = (uint16_t)vidx;
1118 fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info);
1119 fs->nuv = n+1;
1120 return n;
1121} 1202}
1122 1203
1123/* Forward declaration. */ 1204/* Forward declaration. */
1124static void fscope_uvmark(FuncState *fs, BCReg level); 1205static void fscope_uvmark(FuncState *fs, BCReg level);
1125 1206
1126/* Recursively lookup variables in enclosing functions. */ 1207/* Lookup variable name. */
1127static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first) 1208static MSize var_lookup(LexState *ls, ExpDesc *e, GCstr *name)
1128{ 1209{
1129 if (fs) { 1210 MSize vidx = ls->vhash[var_hash(name)];
1130 BCReg reg = var_lookup_local(fs, name); 1211 while (vidx != VINDEX_NONE) {
1131 if ((int32_t)reg >= 0) { /* Local in this function? */ 1212 VarInfo *v = &ls->vstack[vidx];
1132 expr_init(e, VLOCAL, reg); 1213 if (strref(v->name) == name) {
1133 if (!first) 1214 FuncState *fs = ls->fs;
1134 fscope_uvmark(fs, reg); /* Scope now has an upvalue. */ 1215 if (vidx >= fs->vbase) {
1135 return (MSize)(e->u.s.aux = (uint32_t)fs->varmap[reg]); 1216 expr_init(e, VLOCAL, v->slot);
1136 } else { 1217 e->u.s.aux = vidx;
1137 MSize vidx = var_lookup_(fs->prev, name, e, 0); /* Var in outer func? */ 1218 } else {
1138 if ((int32_t)vidx >= 0) { /* Yes, make it an upvalue here. */ 1219 MSize uvidx, nuv = fs->nuv;
1139 e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e); 1220 e->u.s.aux = vidx;
1140 e->k = VUPVAL; 1221 for (uvidx = 0; uvidx < nuv; uvidx++) {
1141 return vidx; 1222 if (fs->uvmap[uvidx] == vidx) { /* Upvalue already exists. */
1223 expr_init(e, VUPVAL, uvidx);
1224 return vidx;
1225 }
1226 }
1227 expr_init(e, VUPVAL, nuv);
1228 for (;;) {
1229 /* Create a new upvalue. */
1230 VarIndex *puvtmp;
1231 checklimit(fs, nuv, LJ_MAX_UPVAL, "upvalues");
1232 fs->uvmap[nuv] = (uint16_t)vidx;
1233 fs->nuv = nuv + 1;
1234 puvtmp = &fs->uvtmp[nuv]; /* Set below. */
1235 fs = fs->prev; /* Continue in parent. */
1236 lj_assertLS(fs != NULL, "variable hash chain broken");
1237 if (vidx >= fs->vbase) { /* Local in that function. */
1238 *puvtmp = vidx;
1239 fscope_uvmark(fs, v->slot);
1240 return vidx;
1241 }
1242 /* Not a local in that function. Find or create upvalue. */
1243 nuv = fs->nuv;
1244 for (uvidx = 0; uvidx < nuv; uvidx++) {
1245 if (fs->uvmap[uvidx] == vidx) { /* Upvalue already exists. */
1246 *puvtmp = LJ_MAX_VSTACK + uvidx;
1247 return vidx;
1248 }
1249 }
1250 /* Not yet an upvalue. Create it and continue. */
1251 *puvtmp = LJ_MAX_VSTACK + nuv;
1252 }
1142 } 1253 }
1254 return vidx;
1143 } 1255 }
1144 } else { /* Not found in any function, must be a global. */ 1256 vidx = v->prev;
1145 expr_init(e, VGLOBAL, 0);
1146 e->u.sval = name;
1147 } 1257 }
1148 return (MSize)-1; /* Global. */ 1258 expr_init(e, VGLOBAL, 0);
1259 e->u.sval = name;
1260 return vidx;
1149} 1261}
1150 1262
1151/* Lookup variable name. */ 1263/* Check for const variable assignment. */
1152#define var_lookup(ls, e) \ 1264static void var_assign(LexState *ls, ExpDesc *e)
1153 var_lookup_((ls)->fs, lex_str(ls), (e), 1) 1265{
1266 if (e->k == VLOCAL || e->k == VUPVAL) {
1267 VarInfo *v = &ls->vstack[e->u.s.aux];
1268 if ((v->info & VSTACK_CONST))
1269 lj_lex_error(ls, 0, LJ_ERR_XCONSTA, strdata(strref(v->name)));
1270 }
1271}
1154 1272
1155/* -- Goto an label handling ---------------------------------------------- */ 1273/* -- Goto and label handling --------------------------------------------- */
1156 1274
1157/* Add a new goto or label. */ 1275/* Add a new goto or label. */
1158static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc) 1276static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc)
@@ -1164,7 +1282,8 @@ static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc)
1164 lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); 1282 lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK);
1165 lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); 1283 lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo);
1166 } 1284 }
1167 lj_assertFS(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL, 1285 lj_assertFS(name == NAME_BREAK || name == NAME_CONT ||
1286 lj_tab_getstr(fs->kt, name) != NULL,
1168 "unanchored label name"); 1287 "unanchored label name");
1169 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ 1288 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1170 setgcref(ls->vstack[vtop].name, obj2gco(name)); 1289 setgcref(ls->vstack[vtop].name, obj2gco(name));
@@ -1219,8 +1338,12 @@ static void gola_resolve(LexState *ls, FuncScope *bl, MSize idx)
1219 lj_assertLS((uintptr_t)name >= VARNAME__MAX, "expected goto name"); 1338 lj_assertLS((uintptr_t)name >= VARNAME__MAX, "expected goto name");
1220 ls->linenumber = ls->fs->bcbase[vg->startpc].line; 1339 ls->linenumber = ls->fs->bcbase[vg->startpc].line;
1221 lj_assertLS(strref(vg->name) != NAME_BREAK, "unexpected break"); 1340 lj_assertLS(strref(vg->name) != NAME_BREAK, "unexpected break");
1222 lj_lex_error(ls, 0, LJ_ERR_XGSCOPE, 1341 if (strref(vg->name) == NAME_CONT) {
1223 strdata(strref(vg->name)), strdata(name)); 1342 lj_lex_error(ls, 0, LJ_ERR_XCSCOPE, strdata(name));
1343 } else {
1344 lj_lex_error(ls, 0, LJ_ERR_XGSCOPE,
1345 strdata(strref(vg->name)), strdata(name));
1346 }
1224 } 1347 }
1225 gola_patch(ls, vg, vl); 1348 gola_patch(ls, vg, vl);
1226 } 1349 }
@@ -1244,8 +1367,10 @@ static void gola_fixup(LexState *ls, FuncScope *bl)
1244 gola_patch(ls, vg, v); 1367 gola_patch(ls, vg, v);
1245 } 1368 }
1246 } else if (gola_isgoto(v)) { 1369 } else if (gola_isgoto(v)) {
1247 if (bl->prev) { /* Propagate goto or break to outer scope. */ 1370 if (bl->prev) { /* Propagate goto, break or continue to outer scope. */
1248 bl->prev->flags |= name == NAME_BREAK ? FSCOPE_BREAK : FSCOPE_GOLA; 1371 bl->prev->flags |= name == NAME_BREAK ? FSCOPE_BREAK :
1372 name == NAME_CONT ? FSCOPE_CONT :
1373 FSCOPE_GOLA;
1249 v->slot = bl->nactvar; 1374 v->slot = bl->nactvar;
1250 if ((bl->flags & FSCOPE_UPVAL)) 1375 if ((bl->flags & FSCOPE_UPVAL))
1251 gola_close(ls, v); 1376 gola_close(ls, v);
@@ -1253,6 +1378,8 @@ static void gola_fixup(LexState *ls, FuncScope *bl)
1253 ls->linenumber = ls->fs->bcbase[v->startpc].line; 1378 ls->linenumber = ls->fs->bcbase[v->startpc].line;
1254 if (name == NAME_BREAK) 1379 if (name == NAME_BREAK)
1255 lj_lex_error(ls, 0, LJ_ERR_XBREAK); 1380 lj_lex_error(ls, 0, LJ_ERR_XBREAK);
1381 else if (name == NAME_CONT)
1382 lj_lex_error(ls, 0, LJ_ERR_XCONT);
1256 else 1383 else
1257 lj_lex_error(ls, 0, LJ_ERR_XLUNDEF, strdata(name)); 1384 lj_lex_error(ls, 0, LJ_ERR_XLUNDEF, strdata(name));
1258 } 1385 }
@@ -1296,21 +1423,33 @@ static void fscope_end(FuncState *fs)
1296 lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc"); 1423 lj_assertFS(bl->nactvar == fs->nactvar, "bad regalloc");
1297 if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL) 1424 if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL)
1298 bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0); 1425 bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0);
1299 if ((bl->flags & FSCOPE_BREAK)) { 1426 lj_assertFS((bl->flags & (FSCOPE_LOOP|FSCOPE_CONT)) != (FSCOPE_LOOP|FSCOPE_CONT), "dangling continue");
1300 if ((bl->flags & FSCOPE_LOOP)) { 1427 if ((bl->flags & (FSCOPE_LOOP|FSCOPE_BREAK)) == (FSCOPE_LOOP|FSCOPE_BREAK)) {
1301 MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc); 1428 MSize idx;
1302 ls->vtop = idx; /* Drop break label immediately. */ 1429 bl->flags &= ~FSCOPE_BREAK;
1303 gola_resolve(ls, bl, idx); 1430 idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc);
1304 } else { /* Need the fixup step to propagate the breaks. */ 1431 ls->vtop = idx; /* Drop break label immediately. */
1305 gola_fixup(ls, bl); 1432 gola_resolve(ls, bl, idx);
1306 return; 1433 }
1307 } 1434 if ((bl->flags & (FSCOPE_GOLA|FSCOPE_BREAK|FSCOPE_CONT))) {
1308 }
1309 if ((bl->flags & FSCOPE_GOLA)) {
1310 gola_fixup(ls, bl); 1435 gola_fixup(ls, bl);
1311 } 1436 }
1312} 1437}
1313 1438
1439/* Add continue label. */
1440static void fscope_continue(FuncState *fs, BCPos cont)
1441{
1442 FuncScope *bl = fs->bl;
1443 if ((bl->flags & FSCOPE_CONT)) {
1444 LexState *ls = fs->ls;
1445 MSize idx;
1446 bl->flags &= ~FSCOPE_CONT;
1447 idx = gola_new(ls, NAME_CONT, VSTACK_LABEL, cont);
1448 ls->vtop = idx; /* Drop continue label immediately. */
1449 gola_resolve(ls, bl, idx);
1450 }
1451}
1452
1314/* Mark scope as having an upvalue. */ 1453/* Mark scope as having an upvalue. */
1315static void fscope_uvmark(FuncState *fs, BCReg level) 1454static void fscope_uvmark(FuncState *fs, BCReg level)
1316{ 1455{
@@ -1460,7 +1599,7 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt,
1460/* Prepare variable info for prototype. */ 1599/* Prepare variable info for prototype. */
1461static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) 1600static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1462{ 1601{
1463 VarInfo *vs =ls->vstack, *ve; 1602 VarInfo *vs = ls->vstack, *ve;
1464 MSize i, n; 1603 MSize i, n;
1465 BCPos lastpc; 1604 BCPos lastpc;
1466 lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */ 1605 lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */
@@ -1633,7 +1772,7 @@ static void fs_init(LexState *ls, FuncState *fs)
1633/* -- Expressions --------------------------------------------------------- */ 1772/* -- Expressions --------------------------------------------------------- */
1634 1773
1635/* Forward declaration. */ 1774/* Forward declaration. */
1636static void expr(LexState *ls, ExpDesc *v); 1775static void expr(LexState *ls, ExpDesc *v, int nocolon);
1637 1776
1638/* Return string expression. */ 1777/* Return string expression. */
1639static void expr_str(LexState *ls, ExpDesc *e) 1778static void expr_str(LexState *ls, ExpDesc *e)
@@ -1680,7 +1819,6 @@ static void expr_field(LexState *ls, ExpDesc *v)
1680 FuncState *fs = ls->fs; 1819 FuncState *fs = ls->fs;
1681 ExpDesc key; 1820 ExpDesc key;
1682 expr_toanyreg(fs, v); 1821 expr_toanyreg(fs, v);
1683 lj_lex_next(ls); /* Skip dot or colon. */
1684 expr_str(ls, &key); 1822 expr_str(ls, &key);
1685 expr_index(fs, v, &key); 1823 expr_index(fs, v, &key);
1686} 1824}
@@ -1689,7 +1827,7 @@ static void expr_field(LexState *ls, ExpDesc *v)
1689static void expr_bracket(LexState *ls, ExpDesc *v) 1827static void expr_bracket(LexState *ls, ExpDesc *v)
1690{ 1828{
1691 lj_lex_next(ls); /* Skip '['. */ 1829 lj_lex_next(ls); /* Skip '['. */
1692 expr(ls, v); 1830 expr(ls, v, 0);
1693 expr_toval(ls->fs, v); 1831 expr_toval(ls->fs, v);
1694 lex_check(ls, ']'); 1832 lex_check(ls, ']');
1695} 1833}
@@ -1731,8 +1869,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
1731 if (!expr_isk(&key)) expr_index(fs, e, &key); 1869 if (!expr_isk(&key)) expr_index(fs, e, &key);
1732 if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; 1870 if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++;
1733 lex_check(ls, '='); 1871 lex_check(ls, '=');
1734 } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) && 1872 } else if (lex_isname(ls->tok) && lj_lex_lookahead(ls) == '=') {
1735 lj_lex_lookahead(ls) == '=') {
1736 expr_str(ls, &key); 1873 expr_str(ls, &key);
1737 lex_check(ls, '='); 1874 lex_check(ls, '=');
1738 nhash++; 1875 nhash++;
@@ -1742,7 +1879,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
1742 narr++; 1879 narr++;
1743 needarr = vcall = 1; 1880 needarr = vcall = 1;
1744 } 1881 }
1745 expr(ls, &val); 1882 expr(ls, &val, 0);
1746 if (expr_isk(&key) && key.k != VKNIL && 1883 if (expr_isk(&key) && key.k != VKNIL &&
1747 (key.k == VKSTR || expr_isk_nojump(&val))) { 1884 (key.k == VKSTR || expr_isk_nojump(&val))) {
1748 TValue k, *v; 1885 TValue k, *v;
@@ -1766,7 +1903,10 @@ static void expr_table(LexState *ls, ExpDesc *e)
1766 } 1903 }
1767 } else { 1904 } else {
1768 nonconst: 1905 nonconst:
1769 if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; } 1906 if (val.k != VCALL) {
1907 expr_toanyreg(fs, &val);
1908 vcall = 0;
1909 }
1770 if (expr_isk(&key)) expr_index(fs, e, &key); 1910 if (expr_isk(&key)) expr_index(fs, e, &key);
1771 bcemit_store(fs, e, &val); 1911 bcemit_store(fs, e, &val);
1772 } 1912 }
@@ -1808,16 +1948,17 @@ static void expr_table(LexState *ls, ExpDesc *e)
1808} 1948}
1809 1949
1810/* Parse function parameters. */ 1950/* Parse function parameters. */
1811static BCReg parse_params(LexState *ls, int needself) 1951static BCReg parse_params(LexState *ls, int needself,
1952 LexToken before, LexToken after)
1812{ 1953{
1813 FuncState *fs = ls->fs; 1954 FuncState *fs = ls->fs;
1814 BCReg nparams = 0; 1955 BCReg nparams = 0;
1815 lex_check(ls, '('); 1956 lex_check(ls, before);
1816 if (needself) 1957 if (needself)
1817 var_new_lit(ls, nparams++, "self"); 1958 var_new_lit(ls, nparams++, "self");
1818 if (ls->tok != ')') { 1959 if (ls->tok != after) {
1819 do { 1960 do {
1820 if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { 1961 if (lex_isname(ls->tok)) {
1821 var_new(ls, nparams++, lex_str(ls)); 1962 var_new(ls, nparams++, lex_str(ls));
1822 } else if (ls->tok == TK_dots) { 1963 } else if (ls->tok == TK_dots) {
1823 lj_lex_next(ls); 1964 lj_lex_next(ls);
@@ -1831,54 +1972,96 @@ static BCReg parse_params(LexState *ls, int needself)
1831 var_add(ls, nparams); 1972 var_add(ls, nparams);
1832 lj_assertFS(fs->nactvar == nparams, "bad regalloc"); 1973 lj_assertFS(fs->nactvar == nparams, "bad regalloc");
1833 bcreg_reserve(fs, nparams); 1974 bcreg_reserve(fs, nparams);
1834 lex_check(ls, ')'); 1975 lex_check(ls, after);
1835 return nparams; 1976 return nparams;
1836} 1977}
1837 1978
1838/* Forward declaration. */ 1979/* Forward declarations. */
1839static void parse_chunk(LexState *ls); 1980static void parse_chunk(LexState *ls);
1981static void parse_return(LexState *ls, int eflags);
1840 1982
1841/* Parse body of a function. */ 1983/* Begin a new function prototype. */
1842static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) 1984static void proto_begin(FuncState *fs, BCLine line, BCReg nparams)
1843{ 1985{
1844 FuncState fs, *pfs = ls->fs; 1986 FuncState *pfs = fs->prev;
1845 FuncScope bl; 1987 fs->linedefined = line;
1846 GCproto *pt; 1988 fs->numparams = (uint8_t)nparams;
1847 ptrdiff_t oldbase = pfs->bcbase - ls->bcstack; 1989 fs->bcbase = pfs->bcbase + pfs->pc;
1848 fs_init(ls, &fs); 1990 fs->bclim = pfs->bclim - pfs->pc;
1849 fscope_begin(&fs, &bl, 0); 1991 bcemit_AD(fs, BC_FUNCF, 0, 0); /* Placeholder. */
1850 fs.linedefined = line; 1992}
1851 fs.numparams = (uint8_t)parse_params(ls, needself); 1993
1852 fs.bcbase = pfs->bcbase + pfs->pc; 1994/* Finish a function prototype. */
1853 fs.bclim = pfs->bclim - pfs->pc; 1995static void proto_finish(LexState *ls, ExpDesc *e, ptrdiff_t oldbase)
1854 bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ 1996{
1855 parse_chunk(ls); 1997 MSize flags = (ls->fs->flags & (PROTO_FFI|PROTO_BITOP));
1856 if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); 1998 GCproto *pt = fs_finish(ls, (ls->lastline = ls->linenumber));
1857 pt = fs_finish(ls, (ls->lastline = ls->linenumber)); 1999 FuncState *pfs = ls->fs;
1858 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ 2000 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
1859 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); 2001 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase);
1860 /* Store new prototype in the constant array of the parent. */ 2002 /* Store new prototype in the constant array of the parent. */
1861 expr_init(e, VRELOCABLE, 2003 expr_init(e, VRELOCABLE,
1862 bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO))); 2004 bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO)));
1863#if LJ_HASFFI 2005 pfs->flags |= (uint8_t)flags; /* Inherited flags. */
1864 pfs->flags |= (fs.flags & PROTO_FFI);
1865#endif
1866 if (!(pfs->flags & PROTO_CHILD)) { 2006 if (!(pfs->flags & PROTO_CHILD)) {
1867 if (pfs->flags & PROTO_HAS_RETURN) 2007 if (pfs->flags & PROTO_HAS_RETURN)
1868 pfs->flags |= PROTO_FIXUP_RETURN; 2008 pfs->flags |= PROTO_FIXUP_RETURN;
1869 pfs->flags |= PROTO_CHILD; 2009 pfs->flags |= PROTO_CHILD;
1870 } 2010 }
2011}
2012
2013/* Parse body of a function. */
2014static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
2015{
2016 ptrdiff_t oldbase = ls->fs->bcbase - ls->bcstack;
2017 FuncState fs;
2018 FuncScope bl;
2019 fs_init(ls, &fs);
2020 fscope_begin(&fs, &bl, 0);
2021 proto_begin(&fs, line, parse_params(ls, needself, '(', ')'));
2022 parse_chunk(ls);
2023 if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line);
2024 proto_finish(ls, e, oldbase);
1871 lj_lex_next(ls); 2025 lj_lex_next(ls);
1872} 2026}
1873 2027
2028/* Parse short function. */
2029static void parse_shortfunc(LexState *ls, ExpDesc *e, GCstr *name,
2030 int eflags, BCLine line)
2031{
2032 ptrdiff_t oldbase = ls->fs->bcbase - ls->bcstack;
2033 FuncState fs;
2034 FuncScope bl;
2035 BCReg nparams = 0;
2036 fs_init(ls, &fs);
2037 fscope_begin(&fs, &bl, 0);
2038 if (name != NULL) {
2039 setboolV(lj_tab_setstr(ls->L, fs.kt, name), 1); /* Anchor in new proto. */
2040 var_new(ls, nparams++, name);
2041 var_add(ls, nparams);
2042 bcreg_reserve(&fs, 1);
2043 } else if (!lex_opt(ls, TK_or_)) {
2044 nparams = parse_params(ls, 0, '|', '|');
2045 }
2046 lex_check(ls, TK_arrow);
2047 proto_begin(&fs, line, nparams);
2048 if (lex_opt(ls, TK_do)) {
2049 parse_chunk(ls);
2050 if (!lex_opt(ls, TK_end)) lex_match(ls, TK_end, TK_do, line);
2051 } else {
2052 parse_return(ls, (eflags | EXPR_F_RET1));
2053 }
2054 proto_finish(ls, e, oldbase);
2055}
2056
1874/* Parse expression list. Last expression is left open. */ 2057/* Parse expression list. Last expression is left open. */
1875static BCReg expr_list(LexState *ls, ExpDesc *v) 2058static BCReg expr_list(LexState *ls, ExpDesc *v)
1876{ 2059{
1877 BCReg n = 1; 2060 BCReg n = 1;
1878 expr(ls, v); 2061 expr(ls, v, 0);
1879 while (lex_opt(ls, ',')) { 2062 while (lex_opt(ls, ',')) {
1880 expr_tonextreg(ls->fs, v); 2063 expr_tonextreg(ls->fs, v);
1881 expr(ls, v); 2064 expr(ls, v, 0);
1882 n++; 2065 n++;
1883 } 2066 }
1884 return n; 2067 return n;
@@ -1931,48 +2114,102 @@ static void parse_args(LexState *ls, ExpDesc *e)
1931 fs->freereg = base+1; /* Leave one result by default. */ 2114 fs->freereg = base+1; /* Leave one result by default. */
1932} 2115}
1933 2116
1934/* Parse primary expression. */ 2117/* Parse primary expression with safe navigation. */
1935static void expr_primary(LexState *ls, ExpDesc *v) 2118static BCPos expr_primary_nav(LexState *ls, ExpDesc *v, int eflags)
1936{ 2119{
1937 FuncState *fs = ls->fs; 2120 FuncState *fs = ls->fs;
2121 BCPos xpc = NO_JMP;
1938 /* Parse prefix expression. */ 2122 /* Parse prefix expression. */
1939 if (ls->tok == '(') { 2123 if (ls->tok == '(') {
1940 BCLine line = ls->linenumber; 2124 BCLine line = ls->linenumber;
1941 lj_lex_next(ls); 2125 lj_lex_next(ls);
1942 expr(ls, v); 2126 expr(ls, v, 0); /* Don't propagate eflags. */
1943 lex_match(ls, ')', '(', line); 2127 lex_match(ls, ')', '(', line);
1944 expr_discharge(ls->fs, v); 2128 expr_discharge(ls->fs, v);
1945 } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { 2129 } else if (lex_isname(ls->tok)) {
1946 var_lookup(ls, v); 2130 BCLine line = ls->linenumber;
2131 GCstr *name = lex_str(ls);
2132 if (!(eflags & EXPR_F_NORES) && ls->tok == TK_arrow) {
2133 parse_shortfunc(ls, v, name, eflags, line);
2134 return xpc;
2135 }
2136 var_lookup(ls, v, name);
1947 } else { 2137 } else {
2138 err:
1948 err_syntax(ls, LJ_ERR_XSYMBOL); 2139 err_syntax(ls, LJ_ERR_XSYMBOL);
1949 } 2140 }
1950 for (;;) { /* Parse multiple expression suffixes. */ 2141 for (;;) { /* Parse multiple expression suffixes. */
1951 if (ls->tok == '.') { 2142 int nav = 0;
1952 expr_field(ls, v); 2143 if (!(eflags & EXPR_F_NONAV) && lex_opt(ls, TK_nav)) {
1953 } else if (ls->tok == '[') { 2144 nav = 1;
2145 expr_toanyreg(fs, v);
2146 bcemit_INS(fs, BCINS_AD(BC_ISEQP, v->u.s.info, VKNIL));
2147 jmp_append(fs, &xpc, bcemit_jmp(fs));
2148 }
2149 if (ls->tok == '[') {
1954 ExpDesc key; 2150 ExpDesc key;
1955 expr_toanyreg(fs, v); 2151 expr_toanyreg(fs, v);
1956 expr_bracket(ls, &key); 2152 expr_bracket(ls, &key);
1957 expr_index(fs, v, &key); 2153 expr_index(fs, v, &key);
1958 } else if (ls->tok == ':') { 2154 } else if (ls->tok == ':') {
1959 ExpDesc key; 2155 ExpDesc key;
1960 lj_lex_next(ls); 2156 if ((eflags & EXPR_F_NOCOLON)) {
2157 if (nav) goto err;
2158 break;
2159 }
2160 lj_lex_next(ls); /* Skip ':'. */
1961 expr_str(ls, &key); 2161 expr_str(ls, &key);
1962 bcemit_method(fs, v, &key); 2162 bcemit_method(fs, v, &key);
1963 parse_args(ls, v); 2163 nav = 0;
2164 if (lex_opt(ls, TK_nav)) {
2165 nav = 1;
2166 bcemit_INS(fs, BCINS_AD(BC_ISEQP, v->u.s.info, VKNIL));
2167 jmp_append(fs, &xpc, bcemit_jmp(fs));
2168 }
2169 goto call;
1964 } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { 2170 } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') {
1965 expr_tonextreg(fs, v); 2171 expr_tonextreg(fs, v);
1966 if (ls->fr2) bcreg_reserve(fs, 1); 2172 if (ls->fr2) bcreg_reserve(fs, 1);
2173 call:
1967 parse_args(ls, v); 2174 parse_args(ls, v);
2175 /* Keep nav VCALL if no suffix follows. */
2176 if (nav && !(eflags & EXPR_F_NORES) &&
2177 !(ls->tok == TK_nav || ls->tok == '[' || ls->tok == ':' ||
2178 ls->tok == '(' || ls->tok == TK_string || ls->tok == '{' ||
2179 ls->tok == '.')) break;
2180 } else if (nav || lex_opt(ls, '.')) {
2181 expr_field(ls, v);
1968 } else { 2182 } else {
1969 break; 2183 break;
1970 } 2184 }
2185 if (nav && !(eflags & EXPR_F_NORES)) {
2186 expr_tonextreg(fs, v);
2187 }
2188 }
2189 return xpc;
2190}
2191
2192/* Parse primary expression. */
2193static void expr_primary(LexState *ls, ExpDesc *v, int eflags)
2194{
2195 BCPos xpc = expr_primary_nav(ls, v, eflags);
2196 if (xpc != NO_JMP) {
2197 FuncState *fs = ls->fs;
2198 BCPos around;
2199 around = bcemit_jmp(fs);
2200 jmp_tohere(fs, xpc);
2201 if (v->k == VCALL) { /* Change to VCALLNAV. Still points to CALL/CALLM. */
2202 v->k = VCALLNAV;
2203 bcemit_AD(fs, BC_KPRI, v->u.s.aux, VKNIL);
2204 } else {
2205 bcemit_AD(fs, BC_KPRI, v->u.s.info, VKNIL);
2206 }
2207 jmp_tohere(fs, around);
1971 } 2208 }
1972} 2209}
1973 2210
1974/* Parse simple expression. */ 2211/* Parse simple expression. */
1975static void expr_simple(LexState *ls, ExpDesc *v) 2212static void expr_simple(LexState *ls, ExpDesc *v, int eflags)
1976{ 2213{
1977 switch (ls->tok) { 2214 switch (ls->tok) {
1978 case TK_number: 2215 case TK_number:
@@ -2009,8 +2246,11 @@ static void expr_simple(LexState *ls, ExpDesc *v)
2009 lj_lex_next(ls); 2246 lj_lex_next(ls);
2010 parse_body(ls, v, 0, ls->linenumber); 2247 parse_body(ls, v, 0, ls->linenumber);
2011 return; 2248 return;
2249 case '|': case TK_or_:
2250 parse_shortfunc(ls, v, NULL, eflags, ls->linenumber);
2251 return;
2012 default: 2252 default:
2013 expr_primary(ls, v); 2253 expr_primary(ls, v, eflags);
2014 return; 2254 return;
2015 } 2255 }
2016 lj_lex_next(ls); 2256 lj_lex_next(ls);
@@ -2035,15 +2275,22 @@ static BinOpr token2binop(LexToken tok)
2035 case '/': return OPR_DIV; 2275 case '/': return OPR_DIV;
2036 case '%': return OPR_MOD; 2276 case '%': return OPR_MOD;
2037 case '^': return OPR_POW; 2277 case '^': return OPR_POW;
2278 case '&': return OPR_BAND;
2279 case '|': return OPR_BOR;
2280 case '~': return OPR_BXOR;
2281 case TK_shl: return OPR_BSHL;
2282 case TK_shr: return OPR_BSHR;
2283 case TK_sar: return OPR_BSAR;
2038 case TK_concat: return OPR_CONCAT; 2284 case TK_concat: return OPR_CONCAT;
2039 case TK_ne: return OPR_NE; 2285 case TK_ne: case TK_ne_: return OPR_NE;
2040 case TK_eq: return OPR_EQ; 2286 case TK_eq: return OPR_EQ;
2041 case '<': return OPR_LT; 2287 case '<': return OPR_LT;
2042 case TK_le: return OPR_LE; 2288 case TK_le: return OPR_LE;
2043 case '>': return OPR_GT; 2289 case '>': return OPR_GT;
2044 case TK_ge: return OPR_GE; 2290 case TK_ge: return OPR_GE;
2045 case TK_and: return OPR_AND; 2291 case TK_and: case TK_and_: return OPR_AND;
2046 case TK_or: return OPR_OR; 2292 case TK_or: case TK_or_: return OPR_OR;
2293 case TK_coal: return OPR_COAL;
2047 default: return OPR_NOBINOPR; 2294 default: return OPR_NOBINOPR;
2048 } 2295 }
2049} 2296}
@@ -2053,69 +2300,91 @@ static const struct {
2053 uint8_t left; /* Left priority. */ 2300 uint8_t left; /* Left priority. */
2054 uint8_t right; /* Right priority. */ 2301 uint8_t right; /* Right priority. */
2055} priority[] = { 2302} priority[] = {
2056 {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */ 2303 {10,10}, {10,10}, {11,11}, {11,11}, {11,11}, /* ADD SUB MUL DIV MOD */
2057 {10,9}, {5,4}, /* POW CONCAT (right associative) */ 2304 {14,13}, /* POW (right associative) */
2305 {6,6}, {4,4}, {5,5}, /* BAND BOR BXOR */
2306 {7,7}, {7,7}, {7,7}, /* BSHL BSHR BSAR */
2307 {9,8}, /* CONCAT (right associative) */
2058 {3,3}, {3,3}, /* EQ NE */ 2308 {3,3}, {3,3}, /* EQ NE */
2059 {3,3}, {3,3}, {3,3}, {3,3}, /* LT GE GT LE */ 2309 {3,3}, {3,3}, {3,3}, {3,3}, /* LT GE GT LE */
2060 {2,2}, {1,1} /* AND OR */ 2310 {2,2}, {1,1}, {1,1} /* AND OR COAL */
2061}; 2311};
2062 2312
2063#define UNARY_PRIORITY 8 /* Priority for unary operators. */ 2313#define UNARY_PRIORITY 12 /* Priority for unary operators. */
2064 2314
2065/* Forward declaration. */ 2315/* Forward declaration. */
2066static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); 2316static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit, int eflags);
2067 2317
2068/* Parse unary expression. */ 2318/* Parse unary expression. */
2069static void expr_unop(LexState *ls, ExpDesc *v) 2319static void expr_unop(LexState *ls, ExpDesc *v, int eflags)
2070{ 2320{
2071 BCOp op; 2321 BCOp op;
2072 if (ls->tok == TK_not) { 2322 if (ls->tok == TK_not || ls->tok == '!') {
2073 op = BC_NOT; 2323 op = BC_NOT;
2074 } else if (ls->tok == '-') { 2324 } else if (ls->tok == '-') {
2075 op = BC_UNM; 2325 op = BC_UNM;
2076 } else if (ls->tok == '#') { 2326 } else if (ls->tok == '#') {
2077 op = BC_LEN; 2327 op = BC_LEN;
2328 } else if (ls->tok == '~') {
2329 op = BC_BNOT;
2078 } else { 2330 } else {
2079 expr_simple(ls, v); 2331 expr_simple(ls, v, eflags);
2080 return; 2332 return;
2081 } 2333 }
2082 lj_lex_next(ls); 2334 lj_lex_next(ls);
2083 expr_binop(ls, v, UNARY_PRIORITY); 2335 expr_binop(ls, v, UNARY_PRIORITY, eflags);
2084 bcemit_unop(ls->fs, op, v); 2336 bcemit_unop(ls->fs, op, v);
2085} 2337}
2086 2338
2087/* Parse binary expressions with priority higher than the limit. */ 2339/* Parse binary expressions with priority higher than the limit. */
2088static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) 2340static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit, int eflags)
2089{ 2341{
2090 BinOpr op; 2342 BinOpr opr;
2091 synlevel_begin(ls); 2343 synlevel_begin(ls);
2092 expr_unop(ls, v); 2344 expr_unop(ls, v, eflags);
2093 op = token2binop(ls->tok); 2345 opr = token2binop(ls->tok);
2094 while (op != OPR_NOBINOPR && priority[op].left > limit) { 2346 while (opr != OPR_NOBINOPR && priority[opr].left > limit) {
2095 ExpDesc v2; 2347 ExpDesc v2;
2096 BinOpr nextop; 2348 BinOpr nextop;
2097 lj_lex_next(ls); 2349 lj_lex_next(ls);
2098 bcemit_binop_left(ls->fs, op, v); 2350 bcemit_binop_left(ls->fs, opr, v);
2099 /* Parse binary expression with higher priority. */ 2351 /* Parse binary expression with higher priority. */
2100 nextop = expr_binop(ls, &v2, priority[op].right); 2352 nextop = expr_binop(ls, &v2, priority[opr].right, eflags);
2101 bcemit_binop(ls->fs, op, v, &v2); 2353 bcemit_binop(ls->fs, opr, v, &v2);
2102 op = nextop; 2354 opr = nextop;
2103 } 2355 }
2104 synlevel_end(ls); 2356 synlevel_end(ls);
2105 return op; /* Return unconsumed binary operator (if any). */ 2357 return opr; /* Return unconsumed binary operator (if any). */
2106} 2358}
2107 2359
2108/* Parse expression. */ 2360/* Parse expression. */
2109static void expr(LexState *ls, ExpDesc *v) 2361static void expr(LexState *ls, ExpDesc *v, int eflags)
2110{ 2362{
2111 expr_binop(ls, v, 0); /* Priority 0: parse whole expression. */ 2363 expr_binop(ls, v, 0, eflags); /* Priority 0: parse whole expression. */
2364 if (lex_opt(ls, '?')) { /* Ternary ?: conditional operator. Right-assoc. */
2365 FuncState *fs = ls->fs;
2366 BCPos escapelist = NO_JMP, cond;
2367 BCReg reg;
2368 bcemit_branch_t(fs, v);
2369 cond = v->f;
2370 expr(ls, v, EXPR_F_NOCOLON); /* Prevent method parsing. Use parentheses. */
2371 expr_tonextreg(fs, v);
2372 reg = v->u.s.info;
2373 jmp_append(fs, &escapelist, bcemit_jmp(fs));
2374 jmp_tohere(fs, cond);
2375 lex_check(ls, ':');
2376 bcreg_free(fs, reg);
2377 expr(ls, v, 0);
2378 expr_tonextreg(fs, v);
2379 jmp_tohere(fs, escapelist);
2380 }
2112} 2381}
2113 2382
2114/* Assign expression to the next register. */ 2383/* Assign expression to the next register. */
2115static void expr_next(LexState *ls) 2384static void expr_next(LexState *ls)
2116{ 2385{
2117 ExpDesc e; 2386 ExpDesc e;
2118 expr(ls, &e); 2387 expr(ls, &e, 0);
2119 expr_tonextreg(ls->fs, &e); 2388 expr_tonextreg(ls->fs, &e);
2120} 2389}
2121 2390
@@ -2123,7 +2392,7 @@ static void expr_next(LexState *ls)
2123static BCPos expr_cond(LexState *ls) 2392static BCPos expr_cond(LexState *ls)
2124{ 2393{
2125 ExpDesc v; 2394 ExpDesc v;
2126 expr(ls, &v); 2395 expr(ls, &v, 0);
2127 if (v.k == VKNIL) v.k = VKFALSE; 2396 if (v.k == VKNIL) v.k = VKFALSE;
2128 bcemit_branch_t(ls->fs, &v); 2397 bcemit_branch_t(ls->fs, &v);
2129 return v.f; 2398 return v.f;
@@ -2137,6 +2406,44 @@ typedef struct LHSVarList {
2137 struct LHSVarList *prev; /* Link to previous LHS variable. */ 2406 struct LHSVarList *prev; /* Link to previous LHS variable. */
2138} LHSVarList; 2407} LHSVarList;
2139 2408
2409/* Parse compound assignment. */
2410static int parse_compound(LexState *ls, ExpDesc *e)
2411{
2412 FuncState *fs;
2413 ExpDesc estore, v;
2414 BinOpr opr;
2415 if (!(e->k >= VLOCAL && e->k <= VINDEXED)) return 0;
2416 opr = token2binop(ls->tok);
2417 /* '^=' aka exponentiation assignment is deliberately omitted to avoid
2418 ** confusion with xor assignment in other computer languages.
2419 ** Use 'a ~= b' for xor assignment. The unequal operator is only valid
2420 ** in expression contexts and assignments are statements.
2421 */
2422 if (opr > OPR_NE || opr == OPR_POW) return 0; /* ORDER OPR */
2423 var_assign(ls, e);
2424 if (opr == OPR_NE) {
2425 if (ls->tok != TK_ne) lj_lex_error(ls, '!', LJ_ERR_XTOKEN, "=");
2426 opr = OPR_BXOR;
2427 } else { /* Can't use lex_check() here. Only allow '+=', not '+ ='. */
2428 if (ls->c != '=') err_token(ls, '=');
2429 lj_lex_next(ls); /* Skip operator. */
2430 }
2431 lj_lex_next(ls); /* Skip '=' or '~=' aka TOK_ne. */
2432 fs = ls->fs;
2433 estore = *e;
2434 if (e->k == VINDEXED) { /* Preserve the base and key for the store. */
2435 BCReg freg = fs->freereg;
2436 expr_discharge(fs, e);
2437 fs->freereg = freg; /* Undo bcreg_free of info and/or aux. */
2438 }
2439 if (opr == OPR_CONCAT) expr_tonextreg(fs, e); else expr_toanyreg(fs, e);
2440 expr(ls, &v, 0);
2441 bcemit_binop(fs, opr, e, &v);
2442 bcemit_store(fs, &estore, e);
2443 /* Don't bother to free VINDEXED info+aux. Done by parse_chunk(). */
2444 return 1;
2445}
2446
2140/* Eliminate write-after-read hazards for local variable assignment. */ 2447/* Eliminate write-after-read hazards for local variable assignment. */
2141static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v) 2448static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v)
2142{ 2449{
@@ -2167,11 +2474,23 @@ static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e)
2167{ 2474{
2168 FuncState *fs = ls->fs; 2475 FuncState *fs = ls->fs;
2169 int32_t extra = (int32_t)nvars - (int32_t)nexps; 2476 int32_t extra = (int32_t)nvars - (int32_t)nexps;
2170 if (e->k == VCALL) { 2477 if (e->k == VCALL || e->k == VCALLNAV) {
2478 BCInsLine *ilp = &fs->bcbase[e->u.s.info];
2171 extra++; /* Compensate for the VCALL itself. */ 2479 extra++; /* Compensate for the VCALL itself. */
2172 if (extra < 0) extra = 0; 2480 if (extra < 0) extra = 0;
2173 setbc_b(bcptr(fs, e), extra+1); /* Fixup call results. */ 2481 setbc_b(&ilp->ins, extra+1); /* Fixup call results. */
2174 if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1); 2482 if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1);
2483 if (e->k == VCALLNAV) { /* Safe navigation result. */
2484 BCPos base = e->u.s.aux;
2485 lj_assertFS((bc_op(ilp[0].ins) == BC_CALL ||
2486 bc_op(ilp[0].ins) == BC_CALLM) &&
2487 bc_op(ilp[1].ins) == BC_JMP &&
2488 bc_op(ilp[2].ins) == BC_KPRI,
2489 "expected CALL|CALLM, JMP, KPRI inside safe navigation");
2490 setbc_a(&ilp[1].ins, base + extra); /* Fixup JMP nactvar. */
2491 if (extra > 1) /* Need more nils. Case extra == 0 is harmless. */
2492 ilp[2].ins = BCINS_AD(BC_KNIL, base, base + extra-1);
2493 }
2175 } else { 2494 } else {
2176 if (e->k != VVOID) 2495 if (e->k != VVOID)
2177 expr_tonextreg(fs, e); /* Close last expression. */ 2496 expr_tonextreg(fs, e); /* Close last expression. */
@@ -2190,10 +2509,11 @@ static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars)
2190{ 2509{
2191 ExpDesc e; 2510 ExpDesc e;
2192 checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX); 2511 checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX);
2512 var_assign(ls, &lh->v);
2193 if (lex_opt(ls, ',')) { /* Collect LHS list and recurse upwards. */ 2513 if (lex_opt(ls, ',')) { /* Collect LHS list and recurse upwards. */
2194 LHSVarList vl; 2514 LHSVarList vl;
2195 vl.prev = lh; 2515 vl.prev = lh;
2196 expr_primary(ls, &vl.v); 2516 expr_primary(ls, &vl.v, EXPR_F_NONAV);
2197 if (vl.v.k == VLOCAL) 2517 if (vl.v.k == VLOCAL)
2198 assign_hazard(ls, lh, &vl.v); 2518 assign_hazard(ls, lh, &vl.v);
2199 checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names"); 2519 checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names");
@@ -2208,6 +2528,11 @@ static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars)
2208 ls->fs->freereg--; 2528 ls->fs->freereg--;
2209 e.k = VRELOCABLE; 2529 e.k = VRELOCABLE;
2210 } else { /* Multiple call results. */ 2530 } else { /* Multiple call results. */
2531 lj_assertLS(bc_op(*bcptr(ls->fs, &e)) == BC_CALL ||
2532 bc_op(*bcptr(ls->fs, &e)) == BC_CALLM ||
2533 bc_op(*bcptr(ls->fs, &e)) == BC_KPRI,
2534 "unexpected call expression bytecode %d in assignment",
2535 bc_op(*bcptr(ls->fs, &e)));
2211 e.u.s.info = e.u.s.aux; /* Base of call is not relocatable. */ 2536 e.u.s.info = e.u.s.aux; /* Base of call is not relocatable. */
2212 e.k = VNONRELOC; 2537 e.k = VNONRELOC;
2213 } 2538 }
@@ -2227,22 +2552,30 @@ static void parse_call_assign(LexState *ls)
2227{ 2552{
2228 FuncState *fs = ls->fs; 2553 FuncState *fs = ls->fs;
2229 LHSVarList vl; 2554 LHSVarList vl;
2230 expr_primary(ls, &vl.v); 2555 BCReg xpc = expr_primary_nav(ls, &vl.v, EXPR_F_NORES);
2231 if (vl.v.k == VCALL) { /* Function call statement. */ 2556 if (vl.v.k == VCALL) { /* Function call statement. */
2232 setbc_b(bcptr(fs, &vl.v), 1); /* No results. */ 2557 setbc_b(bcptr(fs, &vl.v), 1); /* No results. */
2233 } else { /* Start of an assignment. */ 2558 } else { /* Start of an assignment. */
2234 vl.prev = NULL; 2559 lj_assertFS(vl.v.k != VCALLNAV, "unexpected VCALLNAV in statement");
2235 parse_assignment(ls, &vl, 1); 2560 /* Safe navigation is incompatible with parallel assignment. */
2561 checkcond(ls, xpc == NO_JMP || ls->tok != ',', LJ_ERR_XSYNTAX);
2562 if (!parse_compound(ls, &vl.v)) {
2563 vl.prev = NULL;
2564 parse_assignment(ls, &vl, 1);
2565 }
2236 } 2566 }
2567 if (xpc != NO_JMP) jmp_tohere(fs, xpc);
2237} 2568}
2238 2569
2239/* Parse 'local' statement. */ 2570/* Parse 'local' or 'const' statement. */
2240static void parse_local(LexState *ls) 2571static void parse_local(LexState *ls, int vinfo)
2241{ 2572{
2573 lj_lex_next(ls); /* Skip local or const. */
2242 if (lex_opt(ls, TK_function)) { /* Local function declaration. */ 2574 if (lex_opt(ls, TK_function)) { /* Local function declaration. */
2243 ExpDesc v, b; 2575 ExpDesc v, b;
2244 FuncState *fs = ls->fs; 2576 FuncState *fs = ls->fs;
2245 var_new(ls, 0, lex_str(ls)); 2577 MSize vidx = var_new(ls, 0, lex_str(ls));
2578 ls->vstack[vidx].info = (uint8_t)vinfo;
2246 expr_init(&v, VLOCAL, fs->freereg); 2579 expr_init(&v, VLOCAL, fs->freereg);
2247 v.u.s.aux = fs->varmap[fs->freereg]; 2580 v.u.s.aux = fs->varmap[fs->freereg];
2248 bcreg_reserve(fs, 1); 2581 bcreg_reserve(fs, 1);
@@ -2256,9 +2589,23 @@ static void parse_local(LexState *ls)
2256 } else { /* Local variable declaration. */ 2589 } else { /* Local variable declaration. */
2257 ExpDesc e; 2590 ExpDesc e;
2258 BCReg nexps, nvars = 0; 2591 BCReg nexps, nvars = 0;
2259 do { /* Collect LHS. */ 2592 if (vinfo) { /* Multiple consts need to be checked against each other. */
2260 var_new(ls, nvars++, lex_str(ls)); 2593 VarIndex vhsave[LJ_VINDEX_HSIZE];
2261 } while (lex_opt(ls, ',')); 2594 memcpy(vhsave, ls->vhash, sizeof(vhsave));
2595 do { /* Collect LHS. */
2596 MSize vidx = var_new(ls, nvars++, lex_str(ls));
2597 VarInfo *v = &ls->vstack[vidx];
2598 VarHash hash = var_hash(strref(v->name));
2599 v->prev = ls->vhash[hash]; /* Temporarily add to hash. */
2600 ls->vhash[hash] = vidx;
2601 v->info = (uint8_t)vinfo;
2602 } while (lex_opt(ls, ','));
2603 memcpy(ls->vhash, vhsave, sizeof(vhsave)); /* Restore hash anchors. */
2604 } else {
2605 do { /* Collect LHS. */
2606 var_new(ls, nvars++, lex_str(ls));
2607 } while (lex_opt(ls, ','));
2608 }
2262 if (lex_opt(ls, '=')) { /* Optional RHS. */ 2609 if (lex_opt(ls, '=')) { /* Optional RHS. */
2263 nexps = expr_list(ls, &e); 2610 nexps = expr_list(ls, &e);
2264 } else { /* Or implicitly set to nil. */ 2611 } else { /* Or implicitly set to nil. */
@@ -2277,14 +2624,14 @@ static void parse_func(LexState *ls, BCLine line)
2277 ExpDesc v, b; 2624 ExpDesc v, b;
2278 int needself = 0; 2625 int needself = 0;
2279 lj_lex_next(ls); /* Skip 'function'. */ 2626 lj_lex_next(ls); /* Skip 'function'. */
2280 /* Parse function name. */ 2627 var_lookup(ls, &v, lex_str(ls)); /* Parse function name. */
2281 var_lookup(ls, &v); 2628 while (lex_opt(ls, '.')) /* Multiple dot-separated fields. */
2282 while (ls->tok == '.') /* Multiple dot-separated fields. */
2283 expr_field(ls, &v); 2629 expr_field(ls, &v);
2284 if (ls->tok == ':') { /* Optional colon to signify method call. */ 2630 if (lex_opt(ls, ':')) { /* Optional colon to signify method call. */
2285 needself = 1; 2631 needself = 1;
2286 expr_field(ls, &v); 2632 expr_field(ls, &v);
2287 } 2633 }
2634 var_assign(ls, &v);
2288 parse_body(ls, &b, needself, line); 2635 parse_body(ls, &b, needself, line);
2289 fs = ls->fs; 2636 fs = ls->fs;
2290 bcemit_store(fs, &v, &b); 2637 bcemit_store(fs, &v, &b);
@@ -2305,19 +2652,25 @@ static int parse_isend(LexToken tok)
2305} 2652}
2306 2653
2307/* Parse 'return' statement. */ 2654/* Parse 'return' statement. */
2308static void parse_return(LexState *ls) 2655static void parse_return(LexState *ls, int eflags)
2309{ 2656{
2310 BCIns ins; 2657 BCIns ins;
2311 FuncState *fs = ls->fs; 2658 FuncState *fs = ls->fs;
2312 lj_lex_next(ls); /* Skip 'return'. */
2313 fs->flags |= PROTO_HAS_RETURN; 2659 fs->flags |= PROTO_HAS_RETURN;
2314 if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */ 2660 if (!(eflags & EXPR_F_RET1) && (parse_isend(ls->tok) || ls->tok == ';')) {
2315 ins = BCINS_AD(BC_RET0, 0, 1); 2661 ins = BCINS_AD(BC_RET0, 0, 1); /* Bare return. */
2316 } else { /* Return with one or more values. */ 2662 } else { /* Return with one or more values. */
2317 ExpDesc e; /* Receives the _last_ expression in the list. */ 2663 ExpDesc e; /* Receives the _last_ expression in the list. */
2318 BCReg nret = expr_list(ls, &e); 2664 BCReg nret;
2665 if ((eflags & EXPR_F_RET1)) {
2666 expr(ls, &e, eflags);
2667 nret = 1;
2668 } else {
2669 nret = expr_list(ls, &e);
2670 }
2319 if (nret == 1) { /* Return one result. */ 2671 if (nret == 1) { /* Return one result. */
2320 if (e.k == VCALL) { /* Check for tail call. */ 2672 /* Check for tail call. */
2673 if (e.k == VCALL) {
2321#ifdef LUAJIT_DISABLE_TAILCALL 2674#ifdef LUAJIT_DISABLE_TAILCALL
2322 goto notailcall; 2675 goto notailcall;
2323#else 2676#else
@@ -2331,7 +2684,8 @@ static void parse_return(LexState *ls)
2331 ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2); 2684 ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
2332 } 2685 }
2333 } else { 2686 } else {
2334 if (e.k == VCALL) { /* Append all results from a call. */ 2687 if (e.k == VCALL) {
2688 /* Append all results from a call. */
2335 notailcall: 2689 notailcall:
2336 setbc_b(bcptr(fs, &e), 0); 2690 setbc_b(bcptr(fs, &e), 0);
2337 ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar); 2691 ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar);
@@ -2353,6 +2707,13 @@ static void parse_break(LexState *ls)
2353 gola_new(ls, NAME_BREAK, VSTACK_GOTO, bcemit_jmp(ls->fs)); 2707 gola_new(ls, NAME_BREAK, VSTACK_GOTO, bcemit_jmp(ls->fs));
2354} 2708}
2355 2709
2710/* Parse 'continue' statement. */
2711static void parse_continue(LexState *ls)
2712{
2713 ls->fs->bl->flags |= FSCOPE_CONT;
2714 gola_new(ls, NAME_CONT, VSTACK_GOTO, bcemit_jmp(ls->fs));
2715}
2716
2356/* Parse 'goto' statement. */ 2717/* Parse 'goto' statement. */
2357static void parse_goto(LexState *ls) 2718static void parse_goto(LexState *ls)
2358{ 2719{
@@ -2424,6 +2785,7 @@ static void parse_while(LexState *ls, BCLine line)
2424 parse_block(ls); 2785 parse_block(ls);
2425 jmp_patch(fs, bcemit_jmp(fs), start); 2786 jmp_patch(fs, bcemit_jmp(fs), start);
2426 lex_match(ls, TK_end, TK_while, line); 2787 lex_match(ls, TK_end, TK_while, line);
2788 fscope_continue(fs, start);
2427 fscope_end(fs); 2789 fscope_end(fs);
2428 jmp_tohere(fs, condexit); 2790 jmp_tohere(fs, condexit);
2429 jmp_patchins(fs, loop, fs->pc); 2791 jmp_patchins(fs, loop, fs->pc);
@@ -2442,6 +2804,7 @@ static void parse_repeat(LexState *ls, BCLine line)
2442 bcemit_AD(fs, BC_LOOP, fs->nactvar, 0); 2804 bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
2443 parse_chunk(ls); 2805 parse_chunk(ls);
2444 lex_match(ls, TK_until, TK_repeat, line); 2806 lex_match(ls, TK_until, TK_repeat, line);
2807 fscope_continue(fs, fs->pc);
2445 condexit = expr_cond(ls); /* Parse condition (still inside inner scope). */ 2808 condexit = expr_cond(ls); /* Parse condition (still inside inner scope). */
2446 if (!(bl2.flags & FSCOPE_UPVAL)) { /* No upvalues? Just end inner scope. */ 2809 if (!(bl2.flags & FSCOPE_UPVAL)) { /* No upvalues? Just end inner scope. */
2447 fscope_end(fs); 2810 fscope_end(fs);
@@ -2487,6 +2850,7 @@ static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
2487 bcreg_reserve(fs, 1); 2850 bcreg_reserve(fs, 1);
2488 parse_block(ls); 2851 parse_block(ls);
2489 fscope_end(fs); 2852 fscope_end(fs);
2853 fscope_continue(fs, fs->pc);
2490 /* Perform loop inversion. Loop control instructions are at the end. */ 2854 /* Perform loop inversion. Loop control instructions are at the end. */
2491 loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP); 2855 loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP);
2492 fs->bcbase[loopend].line = line; /* Fix line for control ins. */ 2856 fs->bcbase[loopend].line = line; /* Fix line for control ins. */
@@ -2562,6 +2926,7 @@ static void parse_for_iter(LexState *ls, GCstr *indexname)
2562 fscope_end(fs); 2926 fscope_end(fs);
2563 /* Perform loop inversion. Loop control instructions are at the end. */ 2927 /* Perform loop inversion. Loop control instructions are at the end. */
2564 jmp_patchins(fs, loop, fs->pc); 2928 jmp_patchins(fs, loop, fs->pc);
2929 fscope_continue(fs, fs->pc);
2565 bcemit_ABC(fs, isnext ? BC_ITERN : BC_ITERC, base, nvars-3+1, 2+1); 2930 bcemit_ABC(fs, isnext ? BC_ITERN : BC_ITERC, base, nvars-3+1, 2+1);
2566 loopend = bcemit_AJ(fs, BC_ITERL, base, NO_JMP); 2931 loopend = bcemit_AJ(fs, BC_ITERL, base, NO_JMP);
2567 fs->bcbase[loopend-1].line = line; /* Fix line for control ins. */ 2932 fs->bcbase[loopend-1].line = line; /* Fix line for control ins. */
@@ -2651,16 +3016,28 @@ static int parse_stmt(LexState *ls)
2651 parse_func(ls, line); 3016 parse_func(ls, line);
2652 break; 3017 break;
2653 case TK_local: 3018 case TK_local:
2654 lj_lex_next(ls); 3019 parse_local(ls, 0);
2655 parse_local(ls); 3020 break;
3021 case TK_const: {
3022 LexToken tokx = lj_lex_lookahead(ls);
3023 if (!(lex_isname(tokx) || tokx == TK_function))
3024 goto assign; /* Soft keyword. */
3025 parse_local(ls, VSTACK_CONST);
2656 break; 3026 break;
3027 }
2657 case TK_return: 3028 case TK_return:
2658 parse_return(ls); 3029 lj_lex_next(ls);
3030 parse_return(ls, 0);
2659 return 1; /* Must be last. */ 3031 return 1; /* Must be last. */
2660 case TK_break: 3032 case TK_break:
2661 lj_lex_next(ls); 3033 lj_lex_next(ls);
2662 parse_break(ls); 3034 parse_break(ls);
2663 return !LJ_52; /* Must be last in Lua 5.1. */ 3035 return !LJ_52; /* Must be last in Lua 5.1. */
3036 case TK_continue:
3037 if (!parse_isend(lj_lex_lookahead(ls))) goto assign; /* Soft keyword. */
3038 lj_lex_next(ls);
3039 parse_continue(ls);
3040 return 1; /* Must be last. */
2664#if LJ_52 3041#if LJ_52
2665 case ';': 3042 case ';':
2666 lj_lex_next(ls); 3043 lj_lex_next(ls);
@@ -2670,13 +3047,14 @@ static int parse_stmt(LexState *ls)
2670 parse_label(ls); 3047 parse_label(ls);
2671 break; 3048 break;
2672 case TK_goto: 3049 case TK_goto:
2673 if (LJ_52 || lj_lex_lookahead(ls) == TK_name) { 3050 if (LJ_52 || lex_isname(lj_lex_lookahead(ls))) { /* 5.1 soft keyword. */
2674 lj_lex_next(ls); 3051 lj_lex_next(ls);
2675 parse_goto(ls); 3052 parse_goto(ls);
2676 break; 3053 break;
2677 } 3054 }
2678 /* fallthrough */ 3055 /* fallthrough */
2679 default: 3056 default:
3057 assign:
2680 parse_call_assign(ls); 3058 parse_call_assign(ls);
2681 break; 3059 break;
2682 } 3060 }
@@ -2714,6 +3092,7 @@ GCproto *lj_parse(LexState *ls)
2714 setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */ 3092 setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */
2715 incr_top(L); 3093 incr_top(L);
2716 ls->level = 0; 3094 ls->level = 0;
3095 memset(ls->vhash, 0xff, sizeof(ls->vhash));
2717 fs_init(ls, &fs); 3096 fs_init(ls, &fs);
2718 fs.linedefined = 0; 3097 fs.linedefined = 0;
2719 fs.numparams = 0; 3098 fs.numparams = 0;
diff --git a/src/lj_record.c b/src/lj_record.c
index 8a123a61f..6afe2035b 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -17,6 +17,7 @@
17#include "lj_frame.h" 17#include "lj_frame.h"
18#if LJ_HASFFI 18#if LJ_HASFFI
19#include "lj_ctype.h" 19#include "lj_ctype.h"
20#include "lj_crecord.h"
20#endif 21#endif
21#include "lj_bc.h" 22#include "lj_bc.h"
22#include "lj_ff.h" 23#include "lj_ff.h"
@@ -2505,6 +2506,45 @@ void lj_record_ins(jit_State *J)
2505 rc = rec_mm_arith(J, &ix, MM_pow); 2506 rc = rec_mm_arith(J, &ix, MM_pow);
2506 break; 2507 break;
2507 2508
2509 /* -- Bit operators ----------------------------------------------------- */
2510
2511 case BC_BNOT:
2512#if LJ_HASFFI
2513 if (tref_iscdata(rc)) {
2514 rc = recff_bit64_bitop(J, rc, 0, rcv, NULL, IR_BNOT);
2515 break;
2516 }
2517#endif
2518 rc = lj_opt_narrow_tobit(J, rc);
2519 rc = emitir(IRTI(IR_BNOT), rc, 0);
2520 break;
2521
2522 case BC_BAND: case BC_BOR: case BC_BXOR:
2523#if LJ_HASFFI
2524 if (tref_iscdata(rb) || tref_iscdata(rc)) {
2525 rc = recff_bit64_bitop(J, rb, rc, rbv, rcv, (int)op - (int)BC_BAND + (int)IR_BAND);
2526 break;
2527 }
2528#endif
2529 recbit:
2530 rb = lj_opt_narrow_tobit(J, rb);
2531 rc = lj_opt_narrow_tobit(J, rc);
2532 rc = emitir(IRTI((int)op - (int)BC_BAND + (int)IR_BAND), rb, rc);
2533 break;
2534
2535 case BC_BSHL: case BC_BSHR: case BC_BSAR:
2536#if LJ_HASFFI
2537 {
2538 TRef xrb = rb, xrc = rc;
2539 if (recff_bit64_shift(J, &xrb, &xrc, rbv, rcv, (int)op - (int)BC_BSHL + (int)IR_BSHL)) {
2540 rc = xrb;
2541 break;
2542 }
2543 rc = xrc; /* Shift amount may have been converted. */
2544 }
2545#endif
2546 goto recbit;
2547
2508 /* -- Miscellaneous ops ------------------------------------------------- */ 2548 /* -- Miscellaneous ops ------------------------------------------------- */
2509 2549
2510 case BC_CAT: 2550 case BC_CAT:
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc
index d67dbffcc..d9b2bf663 100644
--- a/src/vm_arm.dasc
+++ b/src/vm_arm.dasc
@@ -849,6 +849,26 @@ static void build_subroutines(BuildCtx *ctx)
849 | b ->vmeta_binop // Binop call for compatibility. 849 | b ->vmeta_binop // Binop call for compatibility.
850#endif 850#endif
851 | 851 |
852 |//-- Bit operator metamethods -------------------------------------------
853 |
854 |->vmeta_bnot:
855 | add CARG3, BASE, RC
856 | mov CARG4, CARG3
857 | b >1
858 |
859 |->vmeta_bitop:
860 | add CARG3, BASE, RB
861 | add CARG4, BASE, RC
862 |1:
863 | decode_OP OP, INS
864 | add CARG2, BASE, RA
865 | str BASE, L->base
866 | mov CARG1, L
867 | str PC, SAVE_PC
868 | str OP, ARG5
869 | bl extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
870 | b ->cont_nop
871 |
852 |//-- Call metamethod ---------------------------------------------------- 872 |//-- Call metamethod ----------------------------------------------------
853 | 873 |
854 |->vmeta_call: // Resolve and call __call metamethod. 874 |->vmeta_call: // Resolve and call __call metamethod.
@@ -3376,6 +3396,61 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3376 | ins_next3 3396 | ins_next3
3377 break; 3397 break;
3378 3398
3399 /* -- Bit ops ----------------------------------------------------------- */
3400
3401 case BC_BNOT:
3402 | // RA = dst, RC = src
3403 | lsl RC, RC, #3
3404 | ldrd CARG12, [BASE, RC]
3405 | checktp CARG1, LJ_TISNUM
3406 | bne ->vmeta_bnot
3407 | mvn CARG1, CARG1
3408 | mvn CARG2, #~LJ_TISNUM
3409 | ins_next1
3410 | ins_next2
3411 | strd CARG12, [BASE, RA]
3412 | ins_next3
3413 break;
3414
3415 |.macro ins_bitop, ins, shop
3416 | decode_RB8 RB, INS
3417 | decode_RC8 RC, INS
3418 | // RA = dst*8, RB = src1*8, RC = src2*8
3419 | ldrd CARG12, [BASE, RB]
3420 | ldrd CARG34, [BASE, RC]
3421 | checktp CARG2, LJ_TISNUM
3422 | checktpeq CARG4, LJ_TISNUM
3423 | bne ->vmeta_bitop
3424 |.if shop == 1
3425 | and CARG3, CARG3, #31
3426 |.endif
3427 | ins CARG1, CARG1, CARG3
3428 | mvn CARG2, #~LJ_TISNUM
3429 | ins_next1
3430 | ins_next2
3431 | strd CARG12, [BASE, RA]
3432 | ins_next3
3433 |.endmacro
3434
3435 case BC_BAND:
3436 | ins_bitop and, 0
3437 break;
3438 case BC_BOR:
3439 | ins_bitop orr, 0
3440 break;
3441 case BC_BXOR:
3442 | ins_bitop eor, 0
3443 break;
3444 case BC_BSHL:
3445 | ins_bitop lsl, 1
3446 break;
3447 case BC_BSHR:
3448 | ins_bitop lsr, 1
3449 break;
3450 case BC_BSAR:
3451 | ins_bitop asr, 1
3452 break;
3453
3379 /* -- Constant ops ------------------------------------------------------ */ 3454 /* -- Constant ops ------------------------------------------------------ */
3380 3455
3381 case BC_KSTR: 3456 case BC_KSTR:
diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc
index be8b76a7a..60452fe56 100644
--- a/src/vm_arm64.dasc
+++ b/src/vm_arm64.dasc
@@ -921,6 +921,25 @@ static void build_subroutines(BuildCtx *ctx)
921 | b ->vmeta_binop // Binop call for compatibility. 921 | b ->vmeta_binop // Binop call for compatibility.
922#endif 922#endif
923 | 923 |
924 |//-- Bit operator metamethods -------------------------------------------
925 |
926 |->vmeta_bnot:
927 | add CARG3, BASE, RC, lsl #3
928 | mov CARG4, CARG3
929 | b >1
930 |
931 |->vmeta_bitop:
932 | add CARG3, BASE, RB, lsl #3
933 | add CARG4, BASE, RC, lsl #3
934 |1:
935 | uxtb CARG5w, INSw
936 | add CARG2, BASE, RA, lsl #3
937 | str BASE, L->base
938 | mov CARG1, L
939 | str PC, SAVE_PC
940 | bl extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
941 | b ->cont_nop
942 |
924 |//-- Call metamethod ---------------------------------------------------- 943 |//-- Call metamethod ----------------------------------------------------
925 | 944 |
926 |->vmeta_call: // Resolve and call __call metamethod. 945 |->vmeta_call: // Resolve and call __call metamethod.
@@ -2878,6 +2897,51 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2878 | ins_next 2897 | ins_next
2879 break; 2898 break;
2880 2899
2900 /* -- Bit ops ----------------------------------------------------------- */
2901
2902 case BC_BNOT:
2903 | // RA = dst, RC = src
2904 | ldr CARG1, [BASE, RC, lsl #3]
2905 | checkint CARG1, ->vmeta_bnot
2906 | mvn CARG1w, CARG1w
2907 | add_TISNUM CARG1, CARG1
2908 | str CARG1, [BASE, RA, lsl #3]
2909 | ins_next
2910 break;
2911
2912 |.macro ins_bitop, ins
2913 | decode_RB RB, INS
2914 | and RC, RC, #255
2915 | // RA = dst, RB = src1, RC = src2
2916 | ldr CARG1, [BASE, RB, lsl #3]
2917 | ldr CARG2, [BASE, RC, lsl #3]
2918 | checkint CARG1, ->vmeta_bitop
2919 | checkint CARG2, ->vmeta_bitop
2920 | ins CARG1w, CARG1w, CARG2w
2921 | add_TISNUM CARG1, CARG1
2922 | str CARG1, [BASE, RA, lsl #3]
2923 | ins_next
2924 |.endmacro
2925
2926 case BC_BAND:
2927 | ins_bitop and
2928 break;
2929 case BC_BOR:
2930 | ins_bitop orr
2931 break;
2932 case BC_BXOR:
2933 | ins_bitop eor
2934 break;
2935 case BC_BSHL:
2936 | ins_bitop lsl
2937 break;
2938 case BC_BSHR:
2939 | ins_bitop lsr
2940 break;
2941 case BC_BSAR:
2942 | ins_bitop asr
2943 break;
2944
2881 /* -- Constant ops ------------------------------------------------------ */ 2945 /* -- Constant ops ------------------------------------------------------ */
2882 2946
2883 case BC_KSTR: 2947 case BC_KSTR:
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc
index 9a39edd69..40e15e888 100644
--- a/src/vm_mips.dasc
+++ b/src/vm_mips.dasc
@@ -982,6 +982,25 @@ static void build_subroutines(BuildCtx *ctx)
982 |. nop 982 |. nop
983#endif 983#endif
984 | 984 |
985 |//-- Bit operator metamethods -------------------------------------------
986 |
987 |->vmeta_bnot:
988 | move RC, RB
989 |
990 |->vmeta_bitop:
991 | load_got lj_meta_bitop
992 | decode_OP1 TMP0, INS
993 | sw BASE, L->base
994 | move CARG2, RA
995 | sw PC, SAVE_PC
996 | move CARG3, RB
997 | move CARG4, RC
998 | sw TMP0, ARG5
999 | call_intern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1000 |. move CARG1, L
1001 | b ->cont_nop
1002 |. nop
1003 |
985 |//-- Call metamethod ---------------------------------------------------- 1004 |//-- Call metamethod ----------------------------------------------------
986 | 1005 |
987 |->vmeta_call: // Resolve and call __call metamethod. 1006 |->vmeta_call: // Resolve and call __call metamethod.
@@ -3886,6 +3905,62 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3886 | ins_next2 3905 | ins_next2
3887 break; 3906 break;
3888 3907
3908 /* -- Bit ops ----------------------------------------------------------- */
3909
3910 case BC_BNOT:
3911 | // RA = dst*8, RD = src*8
3912 | addu RB, BASE, RD
3913 | lw TMP0, HI(RB)
3914 | lw CRET1, LO(RB)
3915 | bne TMP0, TISNUM, ->vmeta_bnot
3916 |. addu RA, BASE, RA
3917 | not CRET1, CRET1
3918 | ins_next1
3919 | sw TISNUM, HI(RA)
3920 | sw CRET1, LO(RA)
3921 | ins_next2
3922 break;
3923
3924 |.macro ins_bitop, ins
3925 | // RA = dst*8, RB = src1*8, RC = src2*8
3926 | decode_RB8a RB, INS
3927 | decode_RB8b RB
3928 | decode_RDtoRC8 RC, RD
3929 | addu RB, BASE, RB
3930 | addu RC, BASE, RC
3931 | lw TMP0, HI(RB)
3932 | lw TMP1, HI(RC)
3933 | lw CRET1, LO(RB)
3934 | bne TMP0, TISNUM, ->vmeta_bitop
3935 |. addu RA, BASE, RA
3936 | lw CRET2, LO(RC)
3937 | bne TMP1, TISNUM, ->vmeta_bitop
3938 |. ins CRET1, CRET1, CRET2
3939 | ins_next1
3940 | sw TISNUM, HI(RA)
3941 | sw CRET1, LO(RA)
3942 | ins_next2
3943 |.endmacro
3944
3945 case BC_BAND:
3946 | ins_bitop and
3947 break;
3948 case BC_BOR:
3949 | ins_bitop or
3950 break;
3951 case BC_BXOR:
3952 | ins_bitop xor
3953 break;
3954 case BC_BSHL:
3955 | ins_bitop sllv
3956 break;
3957 case BC_BSHR:
3958 | ins_bitop srlv
3959 break;
3960 case BC_BSAR:
3961 | ins_bitop srav
3962 break;
3963
3889 /* -- Constant ops ------------------------------------------------------ */ 3964 /* -- Constant ops ------------------------------------------------------ */
3890 3965
3891 case BC_KSTR: 3966 case BC_KSTR:
diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc
index 41587e14d..e4a710b4a 100644
--- a/src/vm_mips64.dasc
+++ b/src/vm_mips64.dasc
@@ -1028,6 +1028,24 @@ static void build_subroutines(BuildCtx *ctx)
1028 |. nop 1028 |. nop
1029#endif 1029#endif
1030 | 1030 |
1031 |//-- Bit operator metamethods -------------------------------------------
1032 |
1033 |->vmeta_bnot:
1034 | move RC, RB
1035 |
1036 |->vmeta_bitop:
1037 | load_got lj_meta_bitop
1038 | sd BASE, L->base
1039 | move CARG2, RA
1040 | sd PC, SAVE_PC
1041 | move CARG3, RB
1042 | move CARG4, RC
1043 | decode_OP1 CARG5, INS // CARG5 == RB.
1044 | call_intern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1045 |. move CARG1, L
1046 | b ->cont_nop
1047 |. nop
1048 |
1031 |//-- Call metamethod ---------------------------------------------------- 1049 |//-- Call metamethod ----------------------------------------------------
1032 | 1050 |
1033 |->vmeta_call: // Resolve and call __call metamethod. 1051 |->vmeta_call: // Resolve and call __call metamethod.
@@ -4113,6 +4131,65 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4113 | ins_next2 4131 | ins_next2
4114 break; 4132 break;
4115 4133
4134 /* -- Bit ops ----------------------------------------------------------- */
4135
4136 case BC_BNOT:
4137 | // RA = dst*8, RD = src*8
4138 | daddu RB, BASE, RD
4139 | ld CRET1, 0(RB)
4140 | gettp TMP0, CRET1
4141 | bne TMP0, TISNUM, ->vmeta_bnot
4142 |. daddu RA, BASE, RA
4143 | not CRET1, CRET1
4144 | zextw CRET1, CRET1
4145 | settp CRET1, TISNUM
4146 | ins_next1
4147 | sd CRET1, 0(RA)
4148 | ins_next2
4149 break;
4150
4151 |.macro ins_bitop, ins
4152 | // RA = dst*8, RB = table*8, RC = key*8
4153 | decode_RB8a RB, INS
4154 | decode_RB8b RB
4155 | decode_RDtoRC8 RC, RD
4156 | daddu RB, BASE, RB
4157 | daddu RC, BASE, RC
4158 | ld CRET1, 0(RB)
4159 | ld CRET2, 0(RC)
4160 | gettp TMP0, CRET1
4161 | daddu RA, BASE, RA
4162 | bne TMP0, TISNUM, ->vmeta_bitop
4163 |. gettp TMP1, CRET2
4164 | sextw CRET1, CRET1
4165 | bne TMP1, TISNUM, ->vmeta_bitop
4166 |. ins CRET1, CRET1, CRET2
4167 | zextw CRET1, CRET1
4168 | settp CRET1, TISNUM
4169 | ins_next1
4170 | sd CRET1, 0(RA)
4171 | ins_next2
4172 |.endmacro
4173
4174 case BC_BAND:
4175 | ins_bitop and
4176 break;
4177 case BC_BOR:
4178 | ins_bitop or
4179 break;
4180 case BC_BXOR:
4181 | ins_bitop xor
4182 break;
4183 case BC_BSHL:
4184 | ins_bitop sllv
4185 break;
4186 case BC_BSHR:
4187 | ins_bitop srlv
4188 break;
4189 case BC_BSAR:
4190 | ins_bitop srav
4191 break;
4192
4116 /* -- Constant ops ------------------------------------------------------ */ 4193 /* -- Constant ops ------------------------------------------------------ */
4117 4194
4118 case BC_KSTR: 4195 case BC_KSTR:
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc
index 440bf1c4b..8d257fdf5 100644
--- a/src/vm_ppc.dasc
+++ b/src/vm_ppc.dasc
@@ -1269,6 +1269,25 @@ static void build_subroutines(BuildCtx *ctx)
1269 | b ->vmeta_binop // Binop call for compatibility. 1269 | b ->vmeta_binop // Binop call for compatibility.
1270#endif 1270#endif
1271 | 1271 |
1272 |//-- Bit operator metamethods -------------------------------------------
1273 |
1274 |->vmeta_bnot:
1275 | mr CARG3, RD
1276 | mr CARG4, RD
1277 | b >1
1278 |
1279 |->vmeta_bitop:
1280 | mr CARG3, RB
1281 | mr CARG4, RC
1282 |1:
1283 | add CARG2, BASE, RA
1284 | stp BASE, L->base
1285 | mr CARG1, L
1286 | stw PC, SAVE_PC
1287 | decode_OP1 CARG5, INS // Caveat: CARG5 overlaps INS.
1288 | bl extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1289 | b ->cont_nop
1290 |
1272 |//-- Call metamethod ---------------------------------------------------- 1291 |//-- Call metamethod ----------------------------------------------------
1273 | 1292 |
1274 |->vmeta_call: // Resolve and call __call metamethod. 1293 |->vmeta_call: // Resolve and call __call metamethod.
@@ -4357,6 +4376,87 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4357 | ins_next2 4376 | ins_next2
4358 break; 4377 break;
4359 4378
4379 /* -- Bit ops ----------------------------------------------------------- */
4380
4381 case BC_BNOT:
4382 | lwzux CARG1, RD, BASE
4383 |.if DUALNUM
4384 | lwz CARG2, 4(RD)
4385 | checknum cr0, CARG1
4386 | bne ->vmeta_bnot
4387 |.else
4388 | lfd FARG1, 0(RD)
4389 | checknum cr0, CARG1
4390 | bge ->vmeta_bnot
4391 | fadd FARG1, FARG1, TOBIT
4392 | stfd FARG1, TMPD
4393 | lwz CARG2, TMPD_LO
4394 |.endif
4395 | not CARG2, CARG2
4396 |7:
4397 |.if DUALNUM
4398 | ins_next1
4399 | stwux TISNUM, RA, BASE
4400 | stw CARG2, 4(RA)
4401 |.else
4402 | tonum_u FARG1, CARG2
4403 | ins_next1
4404 | stfdx FARG1, BASE, RA
4405 |.endif
4406 | ins_next2
4407 break;
4408
4409 |.macro ins_bitop, ins, shmod
4410 | // RA = dst*8, RB = src1*8, RC = src2*8
4411 | lwzux CARG1, RB, BASE
4412 | lwzux CARG3, RC, BASE
4413 |.if DUALNUM
4414 | lwz CARG2, 4(RB)
4415 | lwz CARG4, 4(RC)
4416 | checknum cr0, CARG1
4417 | checknum cr1, CARG3
4418 | bne ->vmeta_bitop
4419 | bne cr1, ->vmeta_bitop
4420 |.else
4421 | lfd FARG1, 0(RB)
4422 | lfd FARG2, 0(RC)
4423 | checknum cr0, CARG1
4424 | checknum cr1, CARG3
4425 | bge ->vmeta_bitop
4426 | bge cr1, ->vmeta_bitop
4427 | fadd FARG1, FARG1, TOBIT
4428 | fadd FARG2, FARG2, TOBIT
4429 | stfd FARG1, TMPD
4430 | lwz CARG2, TMPD_LO
4431 | stfd FARG2, TMPD
4432 | lwz CARG4, TMPD_LO
4433 |.endif
4434 |.if shmod == 1
4435 | rlwinm CARG4, CARG4, 0, 27, 31
4436 |.endif
4437 | ins CARG2, CARG2, CARG4
4438 | b <7
4439 |.endmacro
4440
4441 case BC_BAND:
4442 | ins_bitop and, 0
4443 break;
4444 case BC_BOR:
4445 | ins_bitop or, 0
4446 break;
4447 case BC_BXOR:
4448 | ins_bitop xor, 0
4449 break;
4450 case BC_BSHL:
4451 | ins_bitop slw, 1
4452 break;
4453 case BC_BSHR:
4454 | ins_bitop srw, 1
4455 break;
4456 case BC_BSAR:
4457 | ins_bitop sraw, 1
4458 break;
4459
4360 /* -- Constant ops ------------------------------------------------------ */ 4460 /* -- Constant ops ------------------------------------------------------ */
4361 4461
4362 case BC_KSTR: 4462 case BC_KSTR:
diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
index 16af1f299..5769d1cf5 100644
--- a/src/vm_x64.dasc
+++ b/src/vm_x64.dasc
@@ -1093,6 +1093,47 @@ static void build_subroutines(BuildCtx *ctx)
1093 | jmp ->vmeta_binop // Binop call for compatibility. 1093 | jmp ->vmeta_binop // Binop call for compatibility.
1094#endif 1094#endif
1095 | 1095 |
1096 |//-- Bit operator metamethods -------------------------------------------
1097 |
1098 |->vmeta_bnot:
1099 | mov RB, RA
1100 | lea RC, [BASE+RD*8]
1101 | mov RA, RC
1102 | jmp >2
1103 |
1104 |// Caveat: ra=RB rb=RC rc=RA.
1105 |->vmeta_bitop:
1106 |.if DUALNUM
1107 | movzx RCd, PC_RB
1108 | movzx RAd, PC_RC
1109 |.endif
1110 | lea RC, [BASE+RC*8]
1111 | lea RA, [BASE+RA*8]
1112 |2:
1113 |.if X64WIN
1114 | mov CARG3, RC
1115 | mov CARG4, RA
1116 | lea RA, [BASE+RB*8]
1117 | movzx RC, PC_OP
1118 | mov ARG5, RC
1119 | mov L:RB, SAVE_L
1120 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1121 | mov CARG2, RA
1122 | mov CARG1, L:RB // Caveat: CARG1d == RA.
1123 |.else
1124 | lea CARG2, [BASE+RB*8]
1125 | // CARG4 == RA.
1126 | movzx CARG5, PC_OP
1127 | mov L:CARG1, SAVE_L
1128 | mov L:CARG1->base, BASE // Caveat: CARG3d == BASE.
1129 | mov CARG3, RC
1130 | mov L:RB, L:CARG1
1131 |.endif
1132 | mov SAVE_PC, PC
1133 | call extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1134 | mov BASE, L:RB->base
1135 | jmp ->cont_nop
1136 |
1096 |//-- Call metamethod ---------------------------------------------------- 1137 |//-- Call metamethod ----------------------------------------------------
1097 | 1138 |
1098 |->vmeta_call_ra: 1139 |->vmeta_call_ra:
@@ -3416,7 +3457,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3416 |.if DUALNUM 3457 |.if DUALNUM
3417 | ins_arithdn intins 3458 | ins_arithdn intins
3418 |.else 3459 |.else
3419 | ins_arith, sseins 3460 | ins_arith sseins
3420 |.endif 3461 |.endif
3421 |.endmacro 3462 |.endmacro
3422 3463
@@ -3476,6 +3517,88 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3476 | ins_next 3517 | ins_next
3477 break; 3518 break;
3478 3519
3520 /* -- Bit ops ----------------------------------------------------------- */
3521
3522 case BC_BNOT:
3523 | ins_AD // RA = dst, RD = src
3524 |.if DUALNUM
3525 | mov RB, [BASE+RD*8]
3526 | checkint RB, ->vmeta_bnot
3527 | not RBd
3528 | setint RB
3529 | mov [BASE+RA*8], RB
3530 | ins_next
3531 |.else
3532 | checknumtp [BASE+RD*8], ->vmeta_bnot
3533 | movsd xmm0, qword [BASE+RD*8]
3534 | sseconst_tobit xmm1, RB
3535 | addsd xmm0, xmm1
3536 | movd RBd, xmm0
3537 | not RBd
3538 | cvtsi2sd xmm0, RBd
3539 | movsd qword [BASE+RA*8], xmm0
3540 | ins_next
3541 |.endif
3542 break;
3543
3544 |.macro ins_bitop, ins, shift
3545 | ins_A // Really ins_ABC. RB = dst, RC = src1, RA = src2
3546 | // Swap registers around to avoid reloading RA.
3547 | mov RB, RA
3548 | movzx RAd, RCL // Really src2 (C).
3549 | movzx RCd, RCH // Really src1 (B).
3550 |.if DUALNUM
3551 | mov RA, [BASE+RA*8]
3552 | mov RC, [BASE+RC*8]
3553 | checkint RA, ->vmeta_bitop
3554 | checkint RC, ->vmeta_bitop
3555 |.if shift == 1
3556 | ins RCd, cl // Assumes RA is ecx.
3557 |.else
3558 | ins RCd, RAd
3559 |.endif
3560 | setint RC
3561 | mov [BASE+RB*8], RC
3562 |.else
3563 | checknumtp [BASE+RA*8], ->vmeta_bitop
3564 | checknumtp [BASE+RC*8], ->vmeta_bitop
3565 | movsd xmm0, qword [BASE+RA*8]
3566 | movsd xmm1, qword [BASE+RC*8]
3567 | sseconst_tobit xmm2, RC
3568 | addsd xmm0, xmm2
3569 | addsd xmm1, xmm2
3570 | movd RAd, xmm0
3571 | movd RCd, xmm1
3572 |.if shift == 1
3573 | ins RCd, cl // Assumes RA is ecx.
3574 |.else
3575 | ins RCd, RAd
3576 |.endif
3577 | cvtsi2sd xmm0, RCd
3578 | movsd qword [BASE+RB*8], xmm0
3579 |.endif
3580 | ins_next
3581 |.endmacro
3582
3583 case BC_BAND:
3584 | ins_bitop and, 0
3585 break;
3586 case BC_BOR:
3587 | ins_bitop or, 0
3588 break;
3589 case BC_BXOR:
3590 | ins_bitop xor, 0
3591 break;
3592 case BC_BSHL:
3593 | ins_bitop shl, 1
3594 break;
3595 case BC_BSHR:
3596 | ins_bitop shr, 1
3597 break;
3598 case BC_BSAR:
3599 | ins_bitop sar, 1
3600 break;
3601
3479 /* -- Constant ops ------------------------------------------------------ */ 3602 /* -- Constant ops ------------------------------------------------------ */
3480 3603
3481 case BC_KSTR: 3604 case BC_KSTR:
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index 2c9386562..c930168ae 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -1338,6 +1338,53 @@ static void build_subroutines(BuildCtx *ctx)
1338 | jmp ->vmeta_binop // Binop call for compatibility. 1338 | jmp ->vmeta_binop // Binop call for compatibility.
1339#endif 1339#endif
1340 | 1340 |
1341 |//-- Bit operator metamethods -------------------------------------------
1342 |
1343 |->vmeta_bnot:
1344 | mov RB, RA
1345 | lea RC, [BASE+RD*8]
1346 | mov RA, RC
1347 | jmp >2
1348 |
1349 |// Caveat: ra=RB rb=RC rc=RA.
1350 |->vmeta_bitop:
1351 | lea RC, [BASE+RC*8]
1352 | lea RA, [BASE+RA*8]
1353 |2:
1354 |.if X64WIN
1355 | mov CARG3d, RC
1356 | mov CARG4d, RA
1357 | lea RA, [BASE+RB*8]
1358 | movzx RC, PC_OP
1359 | mov ARG5d, RC
1360 | mov L:RB, SAVE_L
1361 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1362 | mov CARG2d, RA
1363 | mov CARG1d, L:RB // Caveat: CARG1d == RA.
1364 |.elif X64
1365 | lea CARG2, [BASE+RB*8]
1366 | // CARG4d == RA.
1367 | movzx CARG5d, PC_OP
1368 | mov L:CARG1d, SAVE_L
1369 | mov L:CARG1d->base, BASE // Caveat: CARG3d == BASE.
1370 | mov CARG3d, RC
1371 | mov L:RB, L:CARG1d
1372 |.else
1373 | lea RB, [BASE+RB*8]
1374 | mov ARG3, RC
1375 | movzx RC, PC_OP
1376 | mov ARG2, RB
1377 | mov L:RB, SAVE_L
1378 | mov ARG4, RA
1379 | mov ARG5, RC
1380 | mov ARG1, L:RB
1381 | mov L:RB->base, BASE
1382 |.endif
1383 | mov SAVE_PC, PC
1384 | call extern lj_meta_bitop // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1385 | mov BASE, L:RB->base
1386 | jmp ->cont_nop
1387 |
1341 |//-- Call metamethod ---------------------------------------------------- 1388 |//-- Call metamethod ----------------------------------------------------
1342 | 1389 |
1343 |->vmeta_call_ra: 1390 |->vmeta_call_ra:
@@ -4006,7 +4053,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4006 |.if DUALNUM 4053 |.if DUALNUM
4007 | ins_arithdn intins 4054 | ins_arithdn intins
4008 |.else 4055 |.else
4009 | ins_arith, sseins 4056 | ins_arith sseins
4010 |.endif 4057 |.endif
4011 |.endmacro 4058 |.endmacro
4012 4059
@@ -4092,6 +4139,89 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4092 | ins_next 4139 | ins_next
4093 break; 4140 break;
4094 4141
4142 /* -- Bit ops ----------------------------------------------------------- */
4143
4144 case BC_BNOT:
4145 | ins_AD // RA = dst, RD = src
4146 |.if DUALNUM
4147 | checkint RD, ->vmeta_bnot
4148 | mov RB, [BASE+RD*8]
4149 | not RB
4150 | mov dword [BASE+RA*8+4], LJ_TISNUM
4151 | mov dword [BASE+RA*8], RB
4152 | ins_next
4153 |.else
4154 | checknum RD, ->vmeta_bnot
4155 | movsd xmm0, qword [BASE+RD*8]
4156 | sseconst_tobit xmm1, RBa
4157 | addsd xmm0, xmm1
4158 | movd RB, xmm0
4159 | not RB
4160 | cvtsi2sd xmm0, RB
4161 | movsd qword [BASE+RA*8], xmm0
4162 | ins_next
4163 |.endif
4164 break;
4165
4166 |.macro ins_bitop, ins, shift
4167 | ins_A // Really ins_ABC. RB = dst, RC = src1, RA = src2
4168 | // Swap registers around to avoid reloading RA.
4169 | mov RB, RA
4170 | movzx RA, RCL // Really src2 (C).
4171 | movzx RC, RCH // Really src1 (B).
4172 |.if DUALNUM
4173 | checkint RA, ->vmeta_bitop
4174 | checkint RC, ->vmeta_bitop
4175 |.if shift == 1
4176 | mov RA, [BASE+RA*8]
4177 | mov RC, [BASE+RC*8]
4178 | ins RC, cl // Assumes RA is ecx.
4179 |.else
4180 | mov RC, [BASE+RC*8]
4181 | ins RC, [BASE+RA*8]
4182 |.endif
4183 | mov dword [BASE+RB*8+4], LJ_TISNUM
4184 | mov dword [BASE+RB*8], RC
4185 |.else
4186 | checknum RA, ->vmeta_bitop
4187 | checknum RC, ->vmeta_bitop
4188 | movsd xmm0, qword [BASE+RA*8]
4189 | movsd xmm1, qword [BASE+RC*8]
4190 | sseconst_tobit xmm2, RCa
4191 | addsd xmm0, xmm2
4192 | addsd xmm1, xmm2
4193 | movd RA, xmm0
4194 | movd RC, xmm1
4195 |.if shift == 1
4196 | ins RC, cl // Assumes RA is ecx.
4197 |.else
4198 | ins RC, RA
4199 |.endif
4200 | cvtsi2sd xmm0, RC
4201 | movsd qword [BASE+RB*8], xmm0
4202 |.endif
4203 | ins_next
4204 |.endmacro
4205
4206 case BC_BAND:
4207 | ins_bitop and, 0
4208 break;
4209 case BC_BOR:
4210 | ins_bitop or, 0
4211 break;
4212 case BC_BXOR:
4213 | ins_bitop xor, 0
4214 break;
4215 case BC_BSHL:
4216 | ins_bitop shl, 1
4217 break;
4218 case BC_BSHR:
4219 | ins_bitop shr, 1
4220 break;
4221 case BC_BSAR:
4222 | ins_bitop sar, 1
4223 break;
4224
4095 /* -- Constant ops ------------------------------------------------------ */ 4225 /* -- Constant ops ------------------------------------------------------ */
4096 4226
4097 case BC_KSTR: 4227 case BC_KSTR: