summaryrefslogtreecommitdiff
path: root/src/lmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lmem.c')
-rw-r--r--src/lmem.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/lmem.c b/src/lmem.c
new file mode 100644
index 00000000..bcb3c8e9
--- /dev/null
+++ b/src/lmem.c
@@ -0,0 +1,113 @@
+/*
+** $Id: lmem.c,v 1.7 1998/06/29 22:03:06 roberto Exp $
+** Interface to Memory Manager
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+#include "lmem.h"
+#include "lstate.h"
+#include "lua.h"
+
+
+
+int luaM_growaux (void **block, unsigned long nelems, int size,
+ char *errormsg, unsigned long limit)
+{
+ if (nelems >= limit)
+ lua_error(errormsg);
+ nelems = (nelems == 0) ? 32 : nelems*2;
+ if (nelems > limit)
+ nelems = limit;
+ *block = luaM_realloc(*block, nelems*size);
+ return (int)nelems;
+}
+
+
+
+#ifndef DEBUG
+
+/*
+** generic allocation routine.
+** real ANSI systems do not need some of these tests,
+** since realloc(NULL, s)==malloc(s) and realloc(b, 0)==free(b).
+** But some systems (e.g. Sun OS) are not that ANSI...
+*/
+void *luaM_realloc (void *block, unsigned long size)
+{
+ size_t s = (size_t)size;
+ if (s != size)
+ lua_error("Allocation Error: Block too big");
+ if (size == 0) {
+ if (block) {
+ free(block);
+ }
+ return NULL;
+ }
+ block = block ? realloc(block, s) : malloc(s);
+ if (block == NULL)
+ lua_error(memEM);
+ return block;
+}
+
+
+
+#else
+/* DEBUG */
+
+#include <string.h>
+
+
+#define HEADER (sizeof(double))
+
+#define MARK 55
+
+unsigned long numblocks = 0;
+unsigned long totalmem = 0;
+
+
+static void *checkblock (void *block)
+{
+ unsigned long *b = (unsigned long *)((char *)block - HEADER);
+ unsigned long size = *b;
+ LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK,
+ "corrupted block");
+ numblocks--;
+ totalmem -= size;
+ return b;
+}
+
+
+void *luaM_realloc (void *block, unsigned long size)
+{
+ unsigned long realsize = HEADER+size+1;
+ if (realsize != (size_t)realsize)
+ lua_error("Allocation Error: Block too big");
+ if (size == 0) { /* ANSI dosen't need this, but some machines... */
+ if (block) {
+ unsigned long *b = (unsigned long *)((char *)block - HEADER);
+ memset(block, -1, *b); /* erase block */
+ block = checkblock(block);
+ free(block);
+ }
+ return NULL;
+ }
+ if (block) {
+ block = checkblock(block);
+ block = (unsigned long *)realloc(block, realsize);
+ }
+ else
+ block = (unsigned long *)malloc(realsize);
+ if (block == NULL)
+ lua_error(memEM);
+ totalmem += size;
+ numblocks++;
+ *(unsigned long *)block = size;
+ *(((char *)block)+size+HEADER) = MARK;
+ return (unsigned long *)((char *)block+HEADER);
+}
+
+
+#endif