From 625ffca739a703906fbc321ef9405514d72480fe Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 13 May 2013 00:34:15 +0200 Subject: [PATCH] Refactor raw object to pointer or string conversions. --- src/Makefile.dep | 4 ++-- src/lib_base.c | 23 ++++------------------- src/lib_string.c | 23 ++--------------------- src/lj_api.c | 12 +----------- src/lj_ffrecord.c | 5 +++-- src/lj_obj.c | 17 ++++++++++++++++- src/lj_obj.h | 3 ++- src/lj_strfmt.c | 31 ++++++++++++++++++++++++++++++- 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 \ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \ lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \ lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ - lj_lib.h lj_libdef.h + lj_strfmt.h lj_lib.h lj_libdef.h lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strfmt.h \ 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 \ lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \ lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \ - lj_vm.h lj_strscan.h lj_recdef.h + lj_vm.h lj_strscan.h lj_strfmt.h lj_recdef.h lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \ 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 @@ #include "lj_dispatch.h" #include "lj_char.h" #include "lj_strscan.h" +#include "lj_strfmt.h" #include "lj_lib.h" /* -- Base library: checks ------------------------------------------------ */ @@ -301,9 +302,6 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) return FFH_RES(1); } -LJLIB_PUSH("nil") -LJLIB_PUSH("false") -LJLIB_PUSH("true") LJLIB_ASM(tostring) LJLIB_REC(.) { TValue *o = lj_lib_checkany(L, 1); @@ -312,23 +310,10 @@ LJLIB_ASM(tostring) LJLIB_REC(.) if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { copyTV(L, L->base-1, mo); /* Replace callable. */ return FFH_TAILCALL; - } else { - GCstr *s; - if (tvisnumber(o)) { - s = lj_str_fromnumber(L, o); - } else if (tvispri(o)) { - s = strV(lj_lib_upvalue(L, -(int32_t)itype(o))); - } else { - if (tvisfunc(o) && isffunc(funcV(o))) - lua_pushfstring(L, "function: builtin#%d", funcV(o)->c.ffid); - else - lua_pushfstring(L, "%s: %p", lj_typename(o), lua_topointer(L, 1)); - /* Note: lua_pushfstring calls the GC which may invalidate o. */ - s = strV(L->top-1); - } - setstrV(L, L->base-1, s); - return FFH_RES(1); } + lj_gc_check(L); + setstrV(L, L->base-1, lj_strfmt_obj(L, L->base)); + return FFH_RES(1); } /* -- 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) copyTV(L, L->base+arg-1, --L->top); return NULL; /* Buffer may be overwritten, retry. */ } - if (tvisnumber(o)) { - return lj_str_fromnumber(L, o); - } else if (tvisnil(o)) { - return lj_str_newlit(L, "nil"); - } else if (tvisfalse(o)) { - return lj_str_newlit(L, "false"); - } else if (tvistrue(o)) { - return lj_str_newlit(L, "true"); - } else { - char buf[8+2+2+16], *p = buf; - if (tvisfunc(o) && isffunc(funcV(o))) { - p = lj_buf_wmem(p, "function: builtin#", 18); - p = lj_str_bufint(p, funcV(o)->c.ffid); - } else { - p = lj_buf_wmem(p, lj_typename(o), strlen(lj_typename(o))); - *p++ = ':'; *p++ = ' '; - p = lj_str_bufptr(p, lua_topointer(L, arg)); - } - return lj_str_new(L, buf, (size_t)(p - buf)); - } + return lj_strfmt_obj(L, o); } LJLIB_CF(string_format) @@ -734,7 +715,7 @@ again: break; case STRFMT_PTR: /* No formatting. */ setsbufP(sb, lj_str_bufptr(lj_buf_more(sb, LJ_STR_PTRBUF), - lua_topointer(L, arg))); + lj_obj_ptr(L->base+arg-1))); break; default: 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) LUA_API const void *lua_topointer(lua_State *L, int idx) { - cTValue *o = index2adr(L, idx); - if (tvisudata(o)) - return uddata(udataV(o)); - else if (tvislightud(o)) - return lightudV(o); - else if (tviscdata(o)) - return cdataptr(cdataV(o)); - else if (tvisgcv(o)) - return gcV(o); - else - return NULL; + return lj_obj_ptr(index2adr(L, idx)); } /* -- 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 @@ #include "lj_dispatch.h" #include "lj_vm.h" #include "lj_strscan.h" +#include "lj_strfmt.h" /* Some local macros to save typing. Undef'd at the end. */ #define IR(ref) (&J->cur.ir[(ref)]) @@ -333,12 +334,12 @@ static void LJ_FASTCALL recff_tostring(jit_State *J, RecordFFData *rd) if (tref_isstr(tr)) { /* Ignore __tostring in the string base metatable. */ /* Pass on result in J->base[0]. */ - } else if (!recff_metacall(J, rd, MM_tostring)) { + } else if (tr && !recff_metacall(J, rd, MM_tostring)) { if (tref_isnumber(tr)) { J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT); } else if (tref_ispri(tr)) { - J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)])); + J->base[0] = lj_ir_kstr(J, lj_strfmt_obj(J->L, &rd->argv[0])); } else { recff_nyiu(J); } 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 */ }; /* Compare two objects without calling metamethods. */ -int lj_obj_equal(cTValue *o1, cTValue *o2) +int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2) { if (itype(o1) == itype(o2)) { if (tvispri(o1)) @@ -33,3 +33,18 @@ int lj_obj_equal(cTValue *o1, cTValue *o2) return numberVnum(o1) == numberVnum(o2); } +/* Return pointer to object or its object data. */ +const void * LJ_FASTCALL lj_obj_ptr(cTValue *o) +{ + if (tvisudata(o)) + return uddata(udataV(o)); + else if (tvislightud(o)) + return lightudV(o); + else if (LJ_HASFFI && tviscdata(o)) + return cdataptr(cdataV(o)); + else if (tvisgcv(o)) + return gcV(o); + else + return NULL; +} + 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]; #define lj_typename(o) (lj_obj_itypename[itypemap(o)]) /* Compare two objects without calling metamethods. */ -LJ_FUNC int lj_obj_equal(cTValue *o1, cTValue *o2); +LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2); +LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(cTValue *o); #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: return fs->len ? STRFMT_LIT : STRFMT_EOF; } -/* -- Format conversions -------------------------------------------------- */ +/* -- Formatted conversions to buffer ------------------------------------- */ /* Add formatted char to buffer. */ 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) return sb; } +/* -- Conversions to strings ---------------------------------------------- */ + +/* Raw conversion of object to string. */ +GCstr *lj_strfmt_obj(lua_State *L, cTValue *o) +{ + if (tvisstr(o)) { + return strV(o); + } else if (tvisnumber(o)) { + return lj_str_fromnumber(L, o); + } else if (tvisnil(o)) { + return lj_str_newlit(L, "nil"); + } else if (tvisfalse(o)) { + return lj_str_newlit(L, "false"); + } else if (tvistrue(o)) { + return lj_str_newlit(L, "true"); + } else { + char buf[8+2+2+16], *p = buf; + p = lj_buf_wmem(p, lj_typename(o), strlen(lj_typename(o))); + *p++ = ':'; *p++ = ' '; + if (tvisfunc(o) && isffunc(funcV(o))) { + p = lj_buf_wmem(p, "builtin#", 8); + p = lj_str_bufint(p, funcV(o)->c.ffid); + } else { + p = lj_str_bufptr(p, lj_obj_ptr(o)); + } + return lj_str_new(L, buf, (size_t)(p - buf)); + } +} + /* -- Internal string formatting ------------------------------------------ */ /* 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); LJ_FUNC SBuf *lj_strfmt_putnum_uint(SBuf *sb, SFormat sf, lua_Number n); LJ_FUNC SBuf *lj_strfmt_putnum(SBuf *sb, SFormat, lua_Number n); +LJ_FUNC GCstr *lj_strfmt_obj(lua_State *L, cTValue *o); + LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, va_list argp); LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...)