Selaa lähdekoodia

function 'type' keeps type names as upvalues to avoid creating strings
everytime it is called

Roberto Ierusalimschy 11 vuotta sitten
vanhempi
commit
16b4110521
1 muutettua tiedostoa jossa 21 lisäystä ja 8 poistoa
  1. 21 8
      lbaselib.c

+ 21 - 8
lbaselib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbaselib.c,v 1.289 2014/06/10 17:41:38 roberto Exp roberto $
+** $Id: lbaselib.c,v 1.290 2014/06/30 19:48:08 roberto Exp roberto $
 ** Basic library
 ** See Copyright Notice in lua.h
 */
@@ -200,9 +200,12 @@ static int luaB_collectgarbage (lua_State *L) {
 }
 
 
+/*
+** This function has all type names as upvalues, to maximize performance.
+*/
 static int luaB_type (lua_State *L) {
   luaL_checkany(L, 1);
-  lua_pushstring(L, luaL_typename(L, 1));
+  lua_pushvalue(L, lua_upvalueindex(lua_type(L, 1) + 1));
   return 1;
 }
 
@@ -461,21 +464,31 @@ static const luaL_Reg base_funcs[] = {
   {"setmetatable", luaB_setmetatable},
   {"tonumber", luaB_tonumber},
   {"tostring", luaB_tostring},
-  {"type", luaB_type},
   {"xpcall", luaB_xpcall},
+  /* placeholders */
+  {"type", NULL},
+  {"_G", NULL},
+  {"_VERSION", NULL},
   {NULL, NULL}
 };
 
 
 LUAMOD_API int luaopen_base (lua_State *L) {
-  /* set global _G */
-  lua_pushglobaltable(L);
-  lua_pushglobaltable(L);
-  lua_setfield(L, -2, "_G");
+  int i;
   /* open lib into global table */
+  lua_pushglobaltable(L);
   luaL_setfuncs(L, base_funcs, 0);
+  /* set global _G */
+  lua_pushvalue(L, -1);
+  lua_setfield(L, -2, "_G");
+  /* set global _VERSION */
   lua_pushliteral(L, LUA_VERSION);
-  lua_setfield(L, -2, "_VERSION");  /* set global _VERSION */
+  lua_setfield(L, -2, "_VERSION");
+  /* set function 'type' with proper upvalues */
+  for (i = 0; i < LUA_NUMTAGS; i++)  /* push all type names as upvalues */
+    lua_pushstring(L, lua_typename(L, i));
+  lua_pushcclosure(L, luaB_type, LUA_NUMTAGS);
+  lua_setfield(L, -2, "type");
   return 1;
 }