aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.dep4
-rw-r--r--src/lib_base.c23
-rw-r--r--src/lib_string.c23
-rw-r--r--src/lj_api.c12
-rw-r--r--src/lj_ffrecord.c5
-rw-r--r--src/lj_obj.c17
-rw-r--r--src/lj_obj.h3
-rw-r--r--src/lj_strfmt.c31
-rw-r--r--src/lj_strfmt.h2
9 files changed, 62 insertions, 58 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep
index 70109c82..1b8b05a0 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -5,7 +5,7 @@ lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
5 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \ 5 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
6 lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \ 6 lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
7 lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ 7 lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
8 lj_lib.h lj_libdef.h 8 lj_strfmt.h lj_lib.h lj_libdef.h
9lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ 9lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
10 lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strfmt.h \ 10 lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strfmt.h \
11 lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h lj_ffdef.h lj_lib.h \ 11 lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h lj_ffdef.h lj_lib.h \
@@ -111,7 +111,7 @@ lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
111 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \ 111 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \
112 lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ 112 lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
113 lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \ 113 lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
114 lj_vm.h lj_strscan.h lj_recdef.h 114 lj_vm.h lj_strscan.h lj_strfmt.h lj_recdef.h
115lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 115lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
116 lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \ 116 lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
117 lj_traceerr.h lj_vm.h 117 lj_traceerr.h lj_vm.h
diff --git a/src/lib_base.c b/src/lib_base.c
index 8fecddea..84bf1ef2 100644
--- a/src/lib_base.c
+++ b/src/lib_base.c
@@ -32,6 +32,7 @@
32#include "lj_dispatch.h" 32#include "lj_dispatch.h"
33#include "lj_char.h" 33#include "lj_char.h"
34#include "lj_strscan.h" 34#include "lj_strscan.h"
35#include "lj_strfmt.h"
35#include "lj_lib.h" 36#include "lj_lib.h"
36 37
37/* -- Base library: checks ------------------------------------------------ */ 38/* -- Base library: checks ------------------------------------------------ */
@@ -301,9 +302,6 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
301 return FFH_RES(1); 302 return FFH_RES(1);
302} 303}
303 304
304LJLIB_PUSH("nil")
305LJLIB_PUSH("false")
306LJLIB_PUSH("true")
307LJLIB_ASM(tostring) LJLIB_REC(.) 305LJLIB_ASM(tostring) LJLIB_REC(.)
308{ 306{
309 TValue *o = lj_lib_checkany(L, 1); 307 TValue *o = lj_lib_checkany(L, 1);
@@ -312,23 +310,10 @@ LJLIB_ASM(tostring) LJLIB_REC(.)
312 if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { 310 if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
313 copyTV(L, L->base-1, mo); /* Replace callable. */ 311 copyTV(L, L->base-1, mo); /* Replace callable. */
314 return FFH_TAILCALL; 312 return FFH_TAILCALL;
315 } else {
316 GCstr *s;
317 if (tvisnumber(o)) {
318 s = lj_str_fromnumber(L, o);
319 } else if (tvispri(o)) {
320 s = strV(lj_lib_upvalue(L, -(int32_t)itype(o)));
321 } else {
322 if (tvisfunc(o) && isffunc(funcV(o)))
323 lua_pushfstring(L, "function: builtin#%d", funcV(o)->c.ffid);
324 else
325 lua_pushfstring(L, "%s: %p", lj_typename(o), lua_topointer(L, 1));
326 /* Note: lua_pushfstring calls the GC which may invalidate o. */
327 s = strV(L->top-1);
328 }
329 setstrV(L, L->base-1, s);
330 return FFH_RES(1);
331 } 313 }
314 lj_gc_check(L);
315 setstrV(L, L->base-1, lj_strfmt_obj(L, L->base));
316 return FFH_RES(1);
332} 317}
333 318
334/* -- Base library: throw and catch errors -------------------------------- */ 319/* -- Base library: throw and catch errors -------------------------------- */
diff --git a/src/lib_string.c b/src/lib_string.c
index b955e933..ec01594f 100644
--- a/src/lib_string.c
+++ b/src/lib_string.c
@@ -655,26 +655,7 @@ static GCstr *string_fmt_tostring(lua_State *L, int arg, int retry)
655 copyTV(L, L->base+arg-1, --L->top); 655 copyTV(L, L->base+arg-1, --L->top);
656 return NULL; /* Buffer may be overwritten, retry. */ 656 return NULL; /* Buffer may be overwritten, retry. */
657 } 657 }
658 if (tvisnumber(o)) { 658 return lj_strfmt_obj(L, o);
659 return lj_str_fromnumber(L, o);
660 } else if (tvisnil(o)) {
661 return lj_str_newlit(L, "nil");
662 } else if (tvisfalse(o)) {
663 return lj_str_newlit(L, "false");
664 } else if (tvistrue(o)) {
665 return lj_str_newlit(L, "true");
666 } else {
667 char buf[8+2+2+16], *p = buf;
668 if (tvisfunc(o) && isffunc(funcV(o))) {
669 p = lj_buf_wmem(p, "function: builtin#", 18);
670 p = lj_str_bufint(p, funcV(o)->c.ffid);
671 } else {
672 p = lj_buf_wmem(p, lj_typename(o), strlen(lj_typename(o)));
673 *p++ = ':'; *p++ = ' ';
674 p = lj_str_bufptr(p, lua_topointer(L, arg));
675 }
676 return lj_str_new(L, buf, (size_t)(p - buf));
677 }
678} 659}
679 660
680LJLIB_CF(string_format) 661LJLIB_CF(string_format)
@@ -734,7 +715,7 @@ again:
734 break; 715 break;
735 case STRFMT_PTR: /* No formatting. */ 716 case STRFMT_PTR: /* No formatting. */
736 setsbufP(sb, lj_str_bufptr(lj_buf_more(sb, LJ_STR_PTRBUF), 717 setsbufP(sb, lj_str_bufptr(lj_buf_more(sb, LJ_STR_PTRBUF),
737 lua_topointer(L, arg))); 718 lj_obj_ptr(L->base+arg-1)));
738 break; 719 break;
739 default: 720 default:
740 lua_assert(0); 721 lua_assert(0);
diff --git a/src/lj_api.c b/src/lj_api.c
index 451e4444..0b7855d7 100644
--- a/src/lj_api.c
+++ b/src/lj_api.c
@@ -546,17 +546,7 @@ LUA_API lua_State *lua_tothread(lua_State *L, int idx)
546 546
547LUA_API const void *lua_topointer(lua_State *L, int idx) 547LUA_API const void *lua_topointer(lua_State *L, int idx)
548{ 548{
549 cTValue *o = index2adr(L, idx); 549 return lj_obj_ptr(index2adr(L, idx));
550 if (tvisudata(o))
551 return uddata(udataV(o));
552 else if (tvislightud(o))
553 return lightudV(o);
554 else if (tviscdata(o))
555 return cdataptr(cdataV(o));
556 else if (tvisgcv(o))
557 return gcV(o);
558 else
559 return NULL;
560} 550}
561 551
562/* -- Stack setters (object creation) ------------------------------------- */ 552/* -- Stack setters (object creation) ------------------------------------- */
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c
index d1aa65c0..bebcf08b 100644
--- a/src/lj_ffrecord.c
+++ b/src/lj_ffrecord.c
@@ -27,6 +27,7 @@
27#include "lj_dispatch.h" 27#include "lj_dispatch.h"
28#include "lj_vm.h" 28#include "lj_vm.h"
29#include "lj_strscan.h" 29#include "lj_strscan.h"
30#include "lj_strfmt.h"
30 31
31/* Some local macros to save typing. Undef'd at the end. */ 32/* Some local macros to save typing. Undef'd at the end. */
32#define IR(ref) (&J->cur.ir[(ref)]) 33#define IR(ref) (&J->cur.ir[(ref)])
@@ -333,12 +334,12 @@ static void LJ_FASTCALL recff_tostring(jit_State *J, RecordFFData *rd)
333 if (tref_isstr(tr)) { 334 if (tref_isstr(tr)) {
334 /* Ignore __tostring in the string base metatable. */ 335 /* Ignore __tostring in the string base metatable. */
335 /* Pass on result in J->base[0]. */ 336 /* Pass on result in J->base[0]. */
336 } else if (!recff_metacall(J, rd, MM_tostring)) { 337 } else if (tr && !recff_metacall(J, rd, MM_tostring)) {
337 if (tref_isnumber(tr)) { 338 if (tref_isnumber(tr)) {
338 J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 339 J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr,
339 tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT); 340 tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT);
340 } else if (tref_ispri(tr)) { 341 } else if (tref_ispri(tr)) {
341 J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)])); 342 J->base[0] = lj_ir_kstr(J, lj_strfmt_obj(J->L, &rd->argv[0]));
342 } else { 343 } else {
343 recff_nyiu(J); 344 recff_nyiu(J);
344 } 345 }
diff --git a/src/lj_obj.c b/src/lj_obj.c
index 322b7bec..208e4955 100644
--- a/src/lj_obj.c
+++ b/src/lj_obj.c
@@ -20,7 +20,7 @@ LJ_DATADEF const char *const lj_obj_itypename[] = { /* ORDER LJ_T */
20}; 20};
21 21
22/* Compare two objects without calling metamethods. */ 22/* Compare two objects without calling metamethods. */
23int lj_obj_equal(cTValue *o1, cTValue *o2) 23int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2)
24{ 24{
25 if (itype(o1) == itype(o2)) { 25 if (itype(o1) == itype(o2)) {
26 if (tvispri(o1)) 26 if (tvispri(o1))
@@ -33,3 +33,18 @@ int lj_obj_equal(cTValue *o1, cTValue *o2)
33 return numberVnum(o1) == numberVnum(o2); 33 return numberVnum(o1) == numberVnum(o2);
34} 34}
35 35
36/* Return pointer to object or its object data. */
37const void * LJ_FASTCALL lj_obj_ptr(cTValue *o)
38{
39 if (tvisudata(o))
40 return uddata(udataV(o));
41 else if (tvislightud(o))
42 return lightudV(o);
43 else if (LJ_HASFFI && tviscdata(o))
44 return cdataptr(cdataV(o));
45 else if (tvisgcv(o))
46 return gcV(o);
47 else
48 return NULL;
49}
50
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 31104429..5a05f38d 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -848,6 +848,7 @@ LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1];
848#define lj_typename(o) (lj_obj_itypename[itypemap(o)]) 848#define lj_typename(o) (lj_obj_itypename[itypemap(o)])
849 849
850/* Compare two objects without calling metamethods. */ 850/* Compare two objects without calling metamethods. */
851LJ_FUNC int lj_obj_equal(cTValue *o1, cTValue *o2); 851LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2);
852LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(cTValue *o);
852 853
853#endif 854#endif
diff --git a/src/lj_strfmt.c b/src/lj_strfmt.c
index 1fe9308d..e8fe2538 100644
--- a/src/lj_strfmt.c
+++ b/src/lj_strfmt.c
@@ -86,7 +86,7 @@ retlit:
86 return fs->len ? STRFMT_LIT : STRFMT_EOF; 86 return fs->len ? STRFMT_LIT : STRFMT_EOF;
87} 87}
88 88
89/* -- Format conversions -------------------------------------------------- */ 89/* -- Formatted conversions to buffer ------------------------------------- */
90 90
91/* Add formatted char to buffer. */ 91/* Add formatted char to buffer. */
92SBuf *lj_strfmt_putchar(SBuf *sb, SFormat sf, int32_t c) 92SBuf *lj_strfmt_putchar(SBuf *sb, SFormat sf, int32_t c)
@@ -294,6 +294,35 @@ SBuf *lj_strfmt_putnum(SBuf *sb, SFormat sf, lua_Number n)
294 return sb; 294 return sb;
295} 295}
296 296
297/* -- Conversions to strings ---------------------------------------------- */
298
299/* Raw conversion of object to string. */
300GCstr *lj_strfmt_obj(lua_State *L, cTValue *o)
301{
302 if (tvisstr(o)) {
303 return strV(o);
304 } else if (tvisnumber(o)) {
305 return lj_str_fromnumber(L, o);
306 } else if (tvisnil(o)) {
307 return lj_str_newlit(L, "nil");
308 } else if (tvisfalse(o)) {
309 return lj_str_newlit(L, "false");
310 } else if (tvistrue(o)) {
311 return lj_str_newlit(L, "true");
312 } else {
313 char buf[8+2+2+16], *p = buf;
314 p = lj_buf_wmem(p, lj_typename(o), strlen(lj_typename(o)));
315 *p++ = ':'; *p++ = ' ';
316 if (tvisfunc(o) && isffunc(funcV(o))) {
317 p = lj_buf_wmem(p, "builtin#", 8);
318 p = lj_str_bufint(p, funcV(o)->c.ffid);
319 } else {
320 p = lj_str_bufptr(p, lj_obj_ptr(o));
321 }
322 return lj_str_new(L, buf, (size_t)(p - buf));
323 }
324}
325
297/* -- Internal string formatting ------------------------------------------ */ 326/* -- Internal string formatting ------------------------------------------ */
298 327
299/* 328/*
diff --git a/src/lj_strfmt.h b/src/lj_strfmt.h
index c440f946..6f3dc0be 100644
--- a/src/lj_strfmt.h
+++ b/src/lj_strfmt.h
@@ -82,6 +82,8 @@ LJ_FUNC SBuf *lj_strfmt_putnum_int(SBuf *sb, SFormat sf, lua_Number n);
82LJ_FUNC SBuf *lj_strfmt_putnum_uint(SBuf *sb, SFormat sf, lua_Number n); 82LJ_FUNC SBuf *lj_strfmt_putnum_uint(SBuf *sb, SFormat sf, lua_Number n);
83LJ_FUNC SBuf *lj_strfmt_putnum(SBuf *sb, SFormat, lua_Number n); 83LJ_FUNC SBuf *lj_strfmt_putnum(SBuf *sb, SFormat, lua_Number n);
84 84
85LJ_FUNC GCstr *lj_strfmt_obj(lua_State *L, cTValue *o);
86
85LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, 87LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt,
86 va_list argp); 88 va_list argp);
87LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...) 89LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...)