private static int luaB_load(lua_State L) { int status; uint l; int top = lua_gettop(L); CharPtr s = lua_tolstring(L, 1, out l); CharPtr mode = luaL_optstring(L, 3, "bt"); if (s != null) /* loading a string? */ { CharPtr chunkname = luaL_optstring(L, 2, s); status = ((checkrights(L, mode, s) != null) || luaL_loadbuffer(L, s, l, chunkname) != 0) ? 1 : 0; } else /* loading from a reader function */ { CharPtr chunkname = luaL_optstring(L, 2, "=(load)"); loaddata ld = new loaddata(); ld.mode = mode; luaL_checktype(L, 1, LUA_TFUNCTION); lua_settop(L, RESERVEDSLOT); /* create reserved slot */ status = lua_load(L, generic_reader, ld, chunkname); } if (status == LUA_OK && top >= 4) /* is there an 'env' argument */ { lua_pushvalue(L, 4); /* environment for loaded function */ lua_setupvalue(L, -2, 1); /* set it as 1st upvalue */ } return(load_aux(L, status)); }
/* ** Reader for generic `load' function: `lua_load' uses the ** stack for internal stuff, so the reader cannot change the ** stack top. Instead, it keeps its resulting string in a ** reserved slot inside the stack. */ private static CharPtr generic_reader(lua_State L, object ud, out uint size) { CharPtr s; loaddata ld = (loaddata )ud; luaL_checkstack(L, 2, "too many nested functions"); lua_pushvalue(L, 1); /* get function */ lua_call(L, 0, 1); /* call it */ if (lua_isnil(L, -1)) { size = 0; return(null); } else if ((s = lua_tostring(L, -1)) != null) { if (ld.mode != null) /* first time? */ { s = checkrights(L, ld.mode, s); /* check mode */ ld.mode = null; /* to avoid further checks */ if (s != null) { luaL_error(L, s); } } lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ return(lua_tolstring(L, RESERVEDSLOT, out size)); } else { luaL_error(L, "reader function must return a string"); size = 0; //FIXME:added return(null); /* to avoid warnings */ } }