lmem.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. ** $Id: lmem.c,v 1.2 1997/11/19 17:29:23 roberto Exp roberto $
  3. ** Interface to Memory Manager
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdlib.h>
  7. #include "lmem.h"
  8. #include "lstate.h"
  9. #include "lua.h"
  10. int luaM_growaux (void **block, unsigned long nelems, int size,
  11. char *errormsg, unsigned long limit)
  12. {
  13. if (nelems >= limit)
  14. lua_error(errormsg);
  15. nelems = (nelems == 0) ? 32 : nelems*2;
  16. if (nelems > limit)
  17. nelems = limit;
  18. *block = luaM_realloc(*block, nelems*size);
  19. return (int)nelems;
  20. }
  21. void *luaM_buffer (unsigned long size)
  22. {
  23. if (size > L->Mbuffsize) {
  24. L->Mbuffsize = size;
  25. L->Mbuffer = luaM_realloc(L->Mbuffer, L->Mbuffsize);
  26. }
  27. return L->Mbuffer;
  28. }
  29. void luaM_clearbuffer (void)
  30. {
  31. L->Mbuffsize /= 2;
  32. L->Mbuffer = luaM_realloc(L->Mbuffer, L->Mbuffsize);
  33. }
  34. #ifndef DEBUG
  35. /*
  36. ** generic allocation routine.
  37. ** real ANSI systems do not need some of these tests,
  38. ** since realloc(NULL, s)==malloc(s) and realloc(b, 0)==free(b).
  39. ** But some systems (e.g. Sun OS) are not that ANSI...
  40. */
  41. void *luaM_realloc (void *block, unsigned long size)
  42. {
  43. size_t s = (size_t)size;
  44. if (s != size)
  45. lua_error("Allocation Error: Block too big");
  46. if (size == 0) {
  47. if (block) {
  48. free(block);
  49. }
  50. return NULL;
  51. }
  52. block = block ? realloc(block, s) : malloc(s);
  53. if (block == NULL)
  54. lua_error(memEM);
  55. return block;
  56. }
  57. #else
  58. /* DEBUG */
  59. #include <assert.h>
  60. #include <string.h>
  61. #define MARK 55
  62. unsigned long numblocks = 0;
  63. unsigned long totalmem = 0;
  64. static void *checkblock (void *block)
  65. {
  66. unsigned long *b = (unsigned long *)block - 1;
  67. unsigned long size = *b;
  68. assert(*(((char *)b)+size+sizeof(unsigned long)) == MARK);
  69. numblocks--;
  70. totalmem -= size;
  71. return b;
  72. }
  73. void *luaM_realloc (void *block, unsigned long size)
  74. {
  75. unsigned long realsize = sizeof(unsigned long)+size+sizeof(char);
  76. if (realsize != (size_t)realsize)
  77. lua_error("Allocation Error: Block too big");
  78. if (size == 0) { /* ANSI doen't need this, but some machines... */
  79. if (block) {
  80. memset(block, -1, *((unsigned long *)block-1)); /* erase block */
  81. block = checkblock(block);
  82. free(block);
  83. }
  84. return NULL;
  85. }
  86. if (block) {
  87. block = checkblock(block);
  88. block = (unsigned long *)realloc(block, realsize);
  89. }
  90. else
  91. block = (unsigned long *)malloc(realsize);
  92. if (block == NULL)
  93. lua_error(memEM);
  94. totalmem += size;
  95. numblocks++;
  96. *(unsigned long *)block = size;
  97. *(((char *)block)+size+sizeof(unsigned long)) = MARK;
  98. return (unsigned long *)block+1;
  99. }
  100. #endif