Jacek Caban : jscript: Added parser memory managment.
Alexandre Julliard
julliard at winehq.org
Thu Sep 4 08:26:58 CDT 2008
Module: wine
Branch: master
Commit: 720e8c625225a91109c77ce11c34e4e2dc3977be
URL: http://source.winehq.org/git/wine.git/?a=commit;h=720e8c625225a91109c77ce11c34e4e2dc3977be
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Sep 3 00:26:10 2008 +0200
jscript: Added parser memory managment.
---
dlls/jscript/Makefile.in | 1 +
dlls/jscript/engine.h | 7 ++-
dlls/jscript/jscript.h | 19 ++++++++
dlls/jscript/jsutils.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/jscript/parser.y | 5 ++
5 files changed, 142 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/Makefile.in b/dlls/jscript/Makefile.in
index 3ccfae3..96d8c37 100644
--- a/dlls/jscript/Makefile.in
+++ b/dlls/jscript/Makefile.in
@@ -12,6 +12,7 @@ C_SRCS = \
engine.c \
jscript.c \
jscript_main.c \
+ jsutils.c \
lex.c
IDL_TLB_SRCS = jsglobal.idl
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 3e558bd..1fad3dd 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -29,6 +29,9 @@ typedef struct _parser_ctx_t {
source_elements_t *source;
BOOL nl;
HRESULT hres;
+
+ jsheap_t tmp_heap;
+ jsheap_t heap;
} parser_ctx_t;
HRESULT script_parse(script_ctx_t*,const WCHAR*,parser_ctx_t**);
@@ -43,12 +46,12 @@ static inline void parser_addref(parser_ctx_t *ctx)
static inline void *parser_alloc(parser_ctx_t *ctx, DWORD size)
{
- return heap_alloc(size); /* FIXME */
+ return jsheap_alloc(&ctx->heap, size);
}
static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
{
- return heap_alloc(size); /* FIXME */
+ return jsheap_alloc(&ctx->tmp_heap, size);
}
typedef struct {
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 6f43adc..ffb3f2b 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -29,6 +29,7 @@
#include "activscp.h"
#include "wine/unicode.h"
+#include "wine/list.h"
typedef struct _script_ctx_t script_ctx_t;
@@ -62,6 +63,19 @@ static void inline script_addref(script_ctx_t *ctx)
HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
+typedef struct {
+ void **blocks;
+ DWORD block_cnt;
+ DWORD last_block;
+ DWORD offset;
+ struct list custom_blocks;
+} jsheap_t;
+
+void jsheap_init(jsheap_t*);
+void *jsheap_alloc(jsheap_t*,DWORD);
+void jsheap_clear(jsheap_t*);
+void jsheap_free(jsheap_t*);
+
extern LONG module_ref;
static inline void lock_module(void)
@@ -84,6 +98,11 @@ static inline void *heap_alloc_zero(size_t len)
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
+static inline void *heap_realloc(void *mem, size_t len)
+{
+ return HeapReAlloc(GetProcessHeap(), 0, mem, len);
+}
+
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
new file mode 100644
index 0000000..4f84e88
--- /dev/null
+++ b/dlls/jscript/jsutils.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "jscript.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+
+#define MIN_BLOCK_SIZE 128
+
+static inline DWORD block_size(DWORD block)
+{
+ return MIN_BLOCK_SIZE << block;
+}
+
+void jsheap_init(jsheap_t *heap)
+{
+ memset(heap, 0, sizeof(*heap));
+ list_init(&heap->custom_blocks);
+}
+
+void *jsheap_alloc(jsheap_t *heap, DWORD size)
+{
+ struct list *list;
+ void *tmp;
+
+ if(!heap->block_cnt) {
+ if(!heap->blocks) {
+ heap->blocks = heap_alloc(sizeof(void*));
+ if(!heap->blocks)
+ return NULL;
+ }
+
+ tmp = heap_alloc(block_size(0));
+ if(!tmp)
+ return NULL;
+
+ heap->blocks[0] = tmp;
+ heap->block_cnt = 1;
+ }
+
+ if(heap->offset + size < block_size(heap->last_block)) {
+ tmp = ((BYTE*)heap->blocks[heap->last_block])+heap->offset;
+ heap->offset += size;
+ return tmp;
+ }
+
+ if(size < block_size(heap->last_block+1)) {
+ if(heap->last_block+1 == heap->block_cnt) {
+ tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
+ if(!tmp)
+ return NULL;
+ heap->blocks = tmp;
+ }
+
+ tmp = heap_alloc(block_size(heap->block_cnt+1));
+ if(!tmp)
+ return NULL;
+
+ heap->blocks[heap->block_cnt++] = tmp;
+
+ heap->last_block++;
+ heap->offset = size;
+ return heap->blocks[heap->last_block];
+ }
+
+ list = heap_alloc(size + sizeof(struct list));
+ if(!list)
+ return NULL;
+
+ list_add_head(&heap->custom_blocks, list);
+ return list+1;
+}
+
+void jsheap_clear(jsheap_t *heap)
+{
+ struct list *tmp;
+
+ while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
+ list_remove(tmp);
+ heap_free(tmp);
+ }
+}
+
+void jsheap_free(jsheap_t *heap)
+{
+ DWORD i;
+
+ jsheap_clear(heap);
+
+ for(i=0; i < heap->block_cnt; i++)
+ heap_free(heap->blocks[i]);
+ heap_free(heap->blocks);
+
+ jsheap_init(heap);
+}
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index dc96647..15584ca 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -1512,6 +1512,7 @@ void parser_release(parser_ctx_t *ctx)
if(--ctx->ref)
return;
+ jsheap_free(&ctx->heap);
heap_free(ctx);
}
@@ -1533,7 +1534,11 @@ HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, parser_ctx_t **ret)
script_addref(ctx);
parser_ctx->script = ctx;
+ jsheap_init(&parser_ctx->tmp_heap);
+ jsheap_init(&parser_ctx->heap);
+
parser_parse(parser_ctx);
+ jsheap_free(&parser_ctx->tmp_heap);
if(FAILED(parser_ctx->hres)) {
hres = parser_ctx->hres;
parser_release(parser_ctx);
More information about the wine-cvs
mailing list