diff options
-rw-r--r-- | src/Makefile.dep | 4 | ||||
-rw-r--r-- | src/lib_base.c | 23 | ||||
-rw-r--r-- | src/lib_string.c | 23 | ||||
-rw-r--r-- | src/lj_api.c | 12 | ||||
-rw-r--r-- | src/lj_ffrecord.c | 5 | ||||
-rw-r--r-- | src/lj_obj.c | 17 | ||||
-rw-r--r-- | src/lj_obj.h | 3 | ||||
-rw-r--r-- | src/lj_strfmt.c | 31 | ||||
-rw-r--r-- | src/lj_strfmt.h | 2 |
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 |
9 | lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ | 9 | lib_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 |
115 | lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 115 | lj_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 | ||
304 | LJLIB_PUSH("nil") | ||
305 | LJLIB_PUSH("false") | ||
306 | LJLIB_PUSH("true") | ||
307 | LJLIB_ASM(tostring) LJLIB_REC(.) | 305 | LJLIB_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 | ||
680 | LJLIB_CF(string_format) | 661 | LJLIB_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 | ||
547 | LUA_API const void *lua_topointer(lua_State *L, int idx) | 547 | LUA_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. */ |
23 | int lj_obj_equal(cTValue *o1, cTValue *o2) | 23 | int 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. */ | ||
37 | const 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. */ |
851 | LJ_FUNC int lj_obj_equal(cTValue *o1, cTValue *o2); | 851 | LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2); |
852 | LJ_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. */ |
92 | SBuf *lj_strfmt_putchar(SBuf *sb, SFormat sf, int32_t c) | 92 | SBuf *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. */ | ||
300 | GCstr *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); | |||
82 | LJ_FUNC SBuf *lj_strfmt_putnum_uint(SBuf *sb, SFormat sf, lua_Number n); | 82 | LJ_FUNC SBuf *lj_strfmt_putnum_uint(SBuf *sb, SFormat sf, lua_Number n); |
83 | LJ_FUNC SBuf *lj_strfmt_putnum(SBuf *sb, SFormat, lua_Number n); | 83 | LJ_FUNC SBuf *lj_strfmt_putnum(SBuf *sb, SFormat, lua_Number n); |
84 | 84 | ||
85 | LJ_FUNC GCstr *lj_strfmt_obj(lua_State *L, cTValue *o); | ||
86 | |||
85 | LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, | 87 | LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, |
86 | va_list argp); | 88 | va_list argp); |
87 | LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...) | 89 | LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...) |