1// The MIT License (MIT) 2 3// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors 4 5// Permission is hereby granted, free of charge, to any person obtaining a copy of 6// this software and associated documentation files (the "Software"), to deal in 7// the Software without restriction, including without limitation the rights to 8// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9// the Software, and to permit persons to whom the Software is furnished to do so, 10// subject to the following conditions: 11 12// The above copyright notice and this permission notice shall be included in all 13// copies or substantial portions of the Software. 14 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22#ifndef SOL_5_X_X_INL 23#define SOL_5_X_X_INL 24 25#include "version.hpp" 26#include "5.2.0.h" 27#include "5.1.0.h" 28#include "5.0.0.h" 29#include "5.x.x.h" 30 31#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM == 501 32 33#include <errno.h> 34#include <string.h> 35 36#define PACKAGE_KEY "_sol.package" 37 38inline int lua_absindex(lua_State *L, int i) { 39 if (i < 0 && i > LUA_REGISTRYINDEX) 40 i += lua_gettop(L) + 1; 41 return i; 42} 43 44inline void lua_copy(lua_State *L, int from, int to) { 45 int abs_to = lua_absindex(L, to); 46 luaL_checkstack(L, 1, "not enough stack slots"); 47 lua_pushvalue(L, from); 48 lua_replace(L, abs_to); 49} 50 51inline void lua_rawgetp(lua_State *L, int i, const void *p) { 52 int abs_i = lua_absindex(L, i); 53 lua_pushlightuserdata(L, (void*)p); 54 lua_rawget(L, abs_i); 55} 56 57inline void lua_rawsetp(lua_State *L, int i, const void *p) { 58 int abs_i = lua_absindex(L, i); 59 luaL_checkstack(L, 1, "not enough stack slots"); 60 lua_pushlightuserdata(L, (void*)p); 61 lua_insert(L, -2); 62 lua_rawset(L, abs_i); 63} 64 65inline void *luaL_testudata(lua_State *L, int i, const char *tname) { 66 void *p = lua_touserdata(L, i); 67 luaL_checkstack(L, 2, "not enough stack slots"); 68 if (p == NULL || !lua_getmetatable(L, i)) 69 return NULL; 70 else { 71 int res = 0; 72 luaL_getmetatable(L, tname); 73 res = lua_rawequal(L, -1, -2); 74 lua_pop(L, 2); 75 if (!res) 76 p = NULL; 77 } 78 return p; 79} 80 81inline lua_Number lua_tonumberx(lua_State *L, int i, int *isnum) { 82 lua_Number n = lua_tonumber(L, i); 83 if (isnum != NULL) { 84 *isnum = (n != 0 || lua_isnumber(L, i)); 85 } 86 return n; 87} 88 89inline static void push_package_table(lua_State *L) { 90 lua_pushliteral(L, PACKAGE_KEY); 91 lua_rawget(L, LUA_REGISTRYINDEX); 92 if (!lua_istable(L, -1)) { 93 lua_pop(L, 1); 94 /* try to get package table from globals */ 95 lua_pushliteral(L, "package"); 96 lua_rawget(L, LUA_GLOBALSINDEX); 97 if (lua_istable(L, -1)) { 98 lua_pushliteral(L, PACKAGE_KEY); 99 lua_pushvalue(L, -2); 100 lua_rawset(L, LUA_REGISTRYINDEX); 101 } 102 } 103} 104 105inline void lua_getuservalue(lua_State *L, int i) { 106 luaL_checktype(L, i, LUA_TUSERDATA); 107 luaL_checkstack(L, 2, "not enough stack slots"); 108 lua_getfenv(L, i); 109 lua_pushvalue(L, LUA_GLOBALSINDEX); 110 if (lua_rawequal(L, -1, -2)) { 111 lua_pop(L, 1); 112 lua_pushnil(L); 113 lua_replace(L, -2); 114 } 115 else { 116 lua_pop(L, 1); 117 push_package_table(L); 118 if (lua_rawequal(L, -1, -2)) { 119 lua_pop(L, 1); 120 lua_pushnil(L); 121 lua_replace(L, -2); 122 } 123 else 124 lua_pop(L, 1); 125 } 126} 127 128inline void lua_setuservalue(lua_State *L, int i) { 129 luaL_checktype(L, i, LUA_TUSERDATA); 130 if (lua_isnil(L, -1)) { 131 luaL_checkstack(L, 1, "not enough stack slots"); 132 lua_pushvalue(L, LUA_GLOBALSINDEX); 133 lua_replace(L, -2); 134 } 135 lua_setfenv(L, i); 136} 137 138/* 139** Adapted from Lua 5.2.0 140*/ 141inline void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) { 142 luaL_checkstack(L, nup + 1, "too many upvalues"); 143 for (; l->name != NULL; l++) { /* fill the table with given functions */ 144 int i; 145 lua_pushstring(L, l->name); 146 for (i = 0; i < nup; i++) /* copy upvalues to the top */ 147 lua_pushvalue(L, -(nup + 1)); 148 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ 149 lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */ 150 } 151 lua_pop(L, nup); /* remove upvalues */ 152} 153 154inline void luaL_setmetatable(lua_State *L, const char *tname) { 155 luaL_checkstack(L, 1, "not enough stack slots"); 156 luaL_getmetatable(L, tname); 157 lua_setmetatable(L, -2); 158} 159 160inline int luaL_getsubtable(lua_State *L, int i, const char *name) { 161 int abs_i = lua_absindex(L, i); 162 luaL_checkstack(L, 3, "not enough stack slots"); 163 lua_pushstring(L, name); 164 lua_gettable(L, abs_i); 165 if (lua_istable(L, -1)) 166 return 1; 167 lua_pop(L, 1); 168 lua_newtable(L); 169 lua_pushstring(L, name); 170 lua_pushvalue(L, -2); 171 lua_settable(L, abs_i); 172 return 0; 173} 174 175#ifndef SOL_LUAJIT 176inline static int countlevels(lua_State *L) { 177 lua_Debug ar; 178 int li = 1, le = 1; 179 /* find an upper bound */ 180 while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } 181 /* do a binary search */ 182 while (li < le) { 183 int m = (li + le) / 2; 184 if (lua_getstack(L, m, &ar)) li = m + 1; 185 else le = m; 186 } 187 return le - 1; 188} 189 190inline static int findfield(lua_State *L, int objidx, int level) { 191 if (level == 0 || !lua_istable(L, -1)) 192 return 0; /* not found */ 193 lua_pushnil(L); /* start 'next' loop */ 194 while (lua_next(L, -2)) { /* for each pair in table */ 195 if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ 196 if (lua_rawequal(L, objidx, -1)) { /* found object? */ 197 lua_pop(L, 1); /* remove value (but keep name) */ 198 return 1; 199 } 200 else if (findfield(L, objidx, level - 1)) { /* try recursively */ 201 lua_remove(L, -2); /* remove table (but keep name) */ 202 lua_pushliteral(L, "."); 203 lua_insert(L, -2); /* place '.' between the two names */ 204 lua_concat(L, 3); 205 return 1; 206 } 207 } 208 lua_pop(L, 1); /* remove value */ 209 } 210 return 0; /* not found */ 211} 212 213inline static int pushglobalfuncname(lua_State *L, lua_Debug *ar) { 214 int top = lua_gettop(L); 215 lua_getinfo(L, "f", ar); /* push function */ 216 lua_pushvalue(L, LUA_GLOBALSINDEX); 217 if (findfield(L, top + 1, 2)) { 218 lua_copy(L, -1, top + 1); /* move name to proper place */ 219 lua_pop(L, 2); /* remove pushed values */ 220 return 1; 221 } 222 else { 223 lua_settop(L, top); /* remove function and global table */ 224 return 0; 225 } 226} 227 228inline static void pushfuncname(lua_State *L, lua_Debug *ar) { 229 if (*ar->namewhat != '\0') /* is there a name? */ 230 lua_pushfstring(L, "function " LUA_QS, ar->name); 231 else if (*ar->what == 'm') /* main? */ 232 lua_pushliteral(L, "main chunk"); 233 else if (*ar->what == 'C') { 234 if (pushglobalfuncname(L, ar)) { 235 lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); 236 lua_remove(L, -2); /* remove name */ 237 } 238 else 239 lua_pushliteral(L, "?"); 240 } 241 else 242 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); 243} 244 245#define LEVELS1 12 /* size of the first part of the stack */ 246#define LEVELS2 10 /* size of the second part of the stack */ 247 248inline void luaL_traceback(lua_State *L, lua_State *L1, 249 const char *msg, int level) { 250 lua_Debug ar; 251 int top = lua_gettop(L); 252 int numlevels = countlevels(L1); 253 int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; 254 if (msg) lua_pushfstring(L, "%s\n", msg); 255 lua_pushliteral(L, "stack traceback:"); 256 while (lua_getstack(L1, level++, &ar)) { 257 if (level == mark) { /* too many levels? */ 258 lua_pushliteral(L, "\n\t..."); /* add a '...' */ 259 level = numlevels - LEVELS2; /* and skip to last ones */ 260 } 261 else { 262 lua_getinfo(L1, "Slnt", &ar); 263 lua_pushfstring(L, "\n\t%s:", ar.short_src); 264 if (ar.currentline > 0) 265 lua_pushfstring(L, "%d:", ar.currentline); 266 lua_pushliteral(L, " in "); 267 pushfuncname(L, &ar); 268 lua_concat(L, lua_gettop(L) - top); 269 } 270 } 271 lua_concat(L, lua_gettop(L) - top); 272} 273#endif 274 275inline const lua_Number *lua_version(lua_State *L) { 276 static const lua_Number version = LUA_VERSION_NUM; 277 if (L == NULL) return &version; 278 // TODO: wonky hacks to get at the inside of the incomplete type lua_State? 279 //else return L->l_G->version; 280 else return &version; 281} 282 283inline static void luaL_checkversion_(lua_State *L, lua_Number ver) { 284 const lua_Number* v = lua_version(L); 285 if (v != lua_version(NULL)) 286 luaL_error(L, "multiple Lua VMs detected"); 287 else if (*v != ver) 288 luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", 289 ver, *v); 290 /* check conversions number -> integer types */ 291 lua_pushnumber(L, -(lua_Number)0x1234); 292 if (lua_tointeger(L, -1) != -0x1234 || 293 lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) 294 luaL_error(L, "bad conversion number->int;" 295 " must recompile Lua with proper settings"); 296 lua_pop(L, 1); 297} 298 299inline void luaL_checkversion(lua_State* L) { 300 luaL_checkversion_(L, LUA_VERSION_NUM); 301} 302 303#ifndef SOL_LUAJIT 304inline int luaL_fileresult(lua_State *L, int stat, const char *fname) { 305 int en = errno; /* calls to Lua API may change this value */ 306 if (stat) { 307 lua_pushboolean(L, 1); 308 return 1; 309 } 310 else { 311 char buf[1024]; 312#if defined(__GLIBC__) || defined(_POSIX_VERSION) 313 strerror_r(en, buf, 1024); 314#else 315 strerror_s(buf, 1024, en); 316#endif 317 lua_pushnil(L); 318 if (fname) 319 lua_pushfstring(L, "%s: %s", fname, buf); 320 else 321 lua_pushstring(L, buf); 322 lua_pushnumber(L, (lua_Number)en); 323 return 3; 324 } 325} 326#endif // luajit 327#endif // Lua 5.0 or Lua 5.1 328 329 330#if SOL_LUA_VERSION == 501 331#include <limits.h> 332 333typedef LUAI_INT32 LUA_INT32; 334 335/********************************************************************/ 336/* extract of 5.2's luaconf.h */ 337/* detects proper defines for faster unsigned<->number conversion */ 338/* see copyright notice at the end of this file */ 339/********************************************************************/ 340 341#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE) 342#define LUA_WIN /* enable goodies for regular Windows platforms */ 343#endif 344 345 346#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ 347 348/* Microsoft compiler on a Pentium (32 bit) ? */ 349#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ 350 351#define LUA_MSASMTRICK 352#define LUA_IEEEENDIAN 0 353#define LUA_NANTRICK 354 355/* pentium 32 bits? */ 356#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ 357 358#define LUA_IEEE754TRICK 359#define LUA_IEEELL 360#define LUA_IEEEENDIAN 0 361#define LUA_NANTRICK 362 363/* pentium 64 bits? */ 364#elif defined(__x86_64) /* }{ */ 365 366#define LUA_IEEE754TRICK 367#define LUA_IEEEENDIAN 0 368 369#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ 370 371#define LUA_IEEE754TRICK 372#define LUA_IEEEENDIAN 1 373 374#else /* }{ */ 375 376/* assume IEEE754 and a 32-bit integer type */ 377#define LUA_IEEE754TRICK 378 379#endif /* } */ 380 381#endif /* } */ 382 383 384/********************************************************************/ 385/* extract of 5.2's llimits.h */ 386/* gives us lua_number2unsigned and lua_unsigned2number */ 387/* see copyright notice just below this one here */ 388/********************************************************************/ 389 390/********************************************************************* 391* This file contains parts of Lua 5.2's source code: 392* 393* Copyright (C) 1994-2013 Lua.org, PUC-Rio. 394* 395* Permission is hereby granted, free of charge, to any person obtaining 396* a copy of this software and associated documentation files (the 397* "Software"), to deal in the Software without restriction, including 398* without limitation the rights to use, copy, modify, merge, publish, 399* distribute, sublicense, and/or sell copies of the Software, and to 400* permit persons to whom the Software is furnished to do so, subject to 401* the following conditions: 402* 403* The above copyright notice and this permission notice shall be 404* included in all copies or substantial portions of the Software. 405* 406* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 407* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 408* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 409* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 410* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 411* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 412* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 413*********************************************************************/ 414 415#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ 416/* trick with Microsoft assembler for X86 */ 417 418#define lua_number2unsigned(i,n) \ 419 {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} 420 421 422#elif defined(LUA_IEEE754TRICK) /* }{ */ 423/* the next trick should work on any machine using IEEE754 with 424a 32-bit int type */ 425 426union compat52_luai_Cast { double l_d; LUA_INT32 l_p[2]; }; 427 428#if !defined(LUA_IEEEENDIAN) /* { */ 429#define LUAI_EXTRAIEEE \ 430 static const union compat52_luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; 431#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) 432#else 433#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN 434#define LUAI_EXTRAIEEE /* empty */ 435#endif /* } */ 436 437#define lua_number2int32(i,n,t) \ 438 { LUAI_EXTRAIEEE \ 439 volatile union compat52_luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ 440 (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } 441 442#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) 443 444#endif /* } */ 445 446 447/* the following definitions always work, but may be slow */ 448 449#if !defined(lua_number2unsigned) /* { */ 450/* the following definition assures proper modulo behavior */ 451#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) 452#include <math.h> 453#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) 454#define lua_number2unsigned(i,n) \ 455 ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) 456#else 457#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) 458#endif 459#endif /* } */ 460 461 462#if !defined(lua_unsigned2number) 463/* on several machines, coercion from unsigned to double is slow, 464so it may be worth to avoid */ 465#define lua_unsigned2number(u) \ 466 (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) 467#endif 468 469/********************************************************************/ 470 471inline static void compat52_call_lua(lua_State *L, char const code[], size_t len, 472 int nargs, int nret) { 473 lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code); 474 if (lua_type(L, -1) != LUA_TFUNCTION) { 475 lua_pop(L, 1); 476 if (luaL_loadbuffer(L, code, len, "=none")) 477 lua_error(L); 478 lua_pushvalue(L, -1); 479 lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code); 480 } 481 lua_insert(L, -nargs - 1); 482 lua_call(L, nargs, nret); 483} 484 485static const char compat52_arith_code[] = { 486 "local op,a,b=...\n" 487 "if op==0 then return a+b\n" 488 "elseif op==1 then return a-b\n" 489 "elseif op==2 then return a*b\n" 490 "elseif op==3 then return a/b\n" 491 "elseif op==4 then return a%b\n" 492 "elseif op==5 then return a^b\n" 493 "elseif op==6 then return -a\n" 494 "end\n" 495}; 496 497inline void lua_arith(lua_State *L, int op) { 498 if (op < LUA_OPADD || op > LUA_OPUNM) 499 luaL_error(L, "invalid 'op' argument for lua_arith"); 500 luaL_checkstack(L, 5, "not enough stack slots"); 501 if (op == LUA_OPUNM) 502 lua_pushvalue(L, -1); 503 lua_pushnumber(L, op); 504 lua_insert(L, -3); 505 compat52_call_lua(L, compat52_arith_code, 506 sizeof(compat52_arith_code) - 1, 3, 1); 507} 508 509static const char compat52_compare_code[] = { 510 "local a,b=...\n" 511 "return a<=b\n" 512}; 513 514inline int lua_compare(lua_State *L, int idx1, int idx2, int op) { 515 int result = 0; 516 switch (op) { 517 case LUA_OPEQ: 518 return lua_equal(L, idx1, idx2); 519 case LUA_OPLT: 520 return lua_lessthan(L, idx1, idx2); 521 case LUA_OPLE: 522 luaL_checkstack(L, 5, "not enough stack slots"); 523 idx1 = lua_absindex(L, idx1); 524 idx2 = lua_absindex(L, idx2); 525 lua_pushvalue(L, idx1); 526 lua_pushvalue(L, idx2); 527 compat52_call_lua(L, compat52_compare_code, 528 sizeof(compat52_compare_code) - 1, 2, 1); 529 result = lua_toboolean(L, -1); 530 lua_pop(L, 1); 531 return result; 532 default: 533 luaL_error(L, "invalid 'op' argument for lua_compare"); 534 } 535 return 0; 536} 537 538inline void lua_pushunsigned(lua_State *L, lua_Unsigned n) { 539 lua_pushnumber(L, lua_unsigned2number(n)); 540} 541 542inline lua_Unsigned luaL_checkunsigned(lua_State *L, int i) { 543 lua_Unsigned result; 544 lua_Number n = lua_tonumber(L, i); 545 if (n == 0 && !lua_isnumber(L, i)) 546 luaL_checktype(L, i, LUA_TNUMBER); 547 lua_number2unsigned(result, n); 548 return result; 549} 550 551inline lua_Unsigned lua_tounsignedx(lua_State *L, int i, int *isnum) { 552 lua_Unsigned result; 553 lua_Number n = lua_tonumberx(L, i, isnum); 554 lua_number2unsigned(result, n); 555 return result; 556} 557 558inline lua_Unsigned luaL_optunsigned(lua_State *L, int i, lua_Unsigned def) { 559 return luaL_opt(L, luaL_checkunsigned, i, def); 560} 561 562inline lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum) { 563 lua_Integer n = lua_tointeger(L, i); 564 if (isnum != NULL) { 565 *isnum = (n != 0 || lua_isnumber(L, i)); 566 } 567 return n; 568} 569 570inline void lua_len(lua_State *L, int i) { 571 switch (lua_type(L, i)) { 572 case LUA_TSTRING: /* fall through */ 573 case LUA_TTABLE: 574 if (!luaL_callmeta(L, i, "__len")) 575 lua_pushnumber(L, (int)lua_objlen(L, i)); 576 break; 577 case LUA_TUSERDATA: 578 if (luaL_callmeta(L, i, "__len")) 579 break; 580 /* maybe fall through */ 581 default: 582 luaL_error(L, "attempt to get length of a %s value", 583 lua_typename(L, lua_type(L, i))); 584 } 585} 586 587inline int luaL_len(lua_State *L, int i) { 588 int res = 0, isnum = 0; 589 luaL_checkstack(L, 1, "not enough stack slots"); 590 lua_len(L, i); 591 res = (int)lua_tointegerx(L, -1, &isnum); 592 lua_pop(L, 1); 593 if (!isnum) 594 luaL_error(L, "object length is not a number"); 595 return res; 596} 597 598inline const char *luaL_tolstring(lua_State *L, int idx, size_t *len) { 599 if (!luaL_callmeta(L, idx, "__tostring")) { 600 int t = lua_type(L, idx); 601 switch (t) { 602 case LUA_TNIL: 603 lua_pushliteral(L, "nil"); 604 break; 605 case LUA_TSTRING: 606 case LUA_TNUMBER: 607 lua_pushvalue(L, idx); 608 break; 609 case LUA_TBOOLEAN: 610 if (lua_toboolean(L, idx)) 611 lua_pushliteral(L, "true"); 612 else 613 lua_pushliteral(L, "false"); 614 break; 615 default: 616 lua_pushfstring(L, "%s: %p", lua_typename(L, t), 617 lua_topointer(L, idx)); 618 break; 619 } 620 } 621 return lua_tolstring(L, -1, len); 622} 623 624inline void luaL_requiref(lua_State *L, char const* modname, 625 lua_CFunction openf, int glb) { 626 luaL_checkstack(L, 3, "not enough stack slots"); 627 lua_pushcfunction(L, openf); 628 lua_pushstring(L, modname); 629 lua_call(L, 1, 1); 630 lua_getglobal(L, "package"); 631 if (lua_istable(L, -1) == 0) { 632 lua_pop(L, 1); 633 lua_createtable(L, 0, 16); 634 lua_setglobal(L, "package"); 635 lua_getglobal(L, "package"); 636 } 637 lua_getfield(L, -1, "loaded"); 638 if (lua_istable(L, -1) == 0) { 639 lua_pop(L, 1); 640 lua_createtable(L, 0, 1); 641 lua_setfield(L, -2, "loaded"); 642 lua_getfield(L, -1, "loaded"); 643 } 644 lua_replace(L, -2); 645 lua_pushvalue(L, -2); 646 lua_setfield(L, -2, modname); 647 lua_pop(L, 1); 648 if (glb) { 649 lua_pushvalue(L, -1); 650 lua_setglobal(L, modname); 651 } 652} 653 654inline void luaL_buffinit(lua_State *L, luaL_Buffer_52 *B) { 655 /* make it crash if used via pointer to a 5.1-style luaL_Buffer */ 656 B->b.p = NULL; 657 B->b.L = NULL; 658 B->b.lvl = 0; 659 /* reuse the buffer from the 5.1-style luaL_Buffer though! */ 660 B->ptr = B->b.buffer; 661 B->capacity = LUAL_BUFFERSIZE; 662 B->nelems = 0; 663 B->L2 = L; 664} 665 666inline char *luaL_prepbuffsize(luaL_Buffer_52 *B, size_t s) { 667 if (B->capacity - B->nelems < s) { /* needs to grow */ 668 char* newptr = NULL; 669 size_t newcap = B->capacity * 2; 670 if (newcap - B->nelems < s) 671 newcap = B->nelems + s; 672 if (newcap < B->capacity) /* overflow */ 673 luaL_error(B->L2, "buffer too large"); 674 newptr = (char*)lua_newuserdata(B->L2, newcap); 675 memcpy(newptr, B->ptr, B->nelems); 676 if (B->ptr != B->b.buffer) 677 lua_replace(B->L2, -2); /* remove old buffer */ 678 B->ptr = newptr; 679 B->capacity = newcap; 680 } 681 return B->ptr + B->nelems; 682} 683 684inline void luaL_addlstring(luaL_Buffer_52 *B, const char *s, size_t l) { 685 memcpy(luaL_prepbuffsize(B, l), s, l); 686 luaL_addsize(B, l); 687} 688 689inline void luaL_addvalue(luaL_Buffer_52 *B) { 690 size_t len = 0; 691 const char *s = lua_tolstring(B->L2, -1, &len); 692 if (!s) 693 luaL_error(B->L2, "cannot convert value to string"); 694 if (B->ptr != B->b.buffer) 695 lua_insert(B->L2, -2); /* userdata buffer must be at stack top */ 696 luaL_addlstring(B, s, len); 697 lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1); 698} 699 700inline void luaL_pushresult(luaL_Buffer_52 *B) { 701 lua_pushlstring(B->L2, B->ptr, B->nelems); 702 if (B->ptr != B->b.buffer) 703 lua_replace(B->L2, -2); /* remove userdata buffer */ 704} 705 706#endif /* SOL_LUA_VERSION == 501 */ 707 708#endif // SOL_5_X_X_INL 709