vbscript: Make vbscode_t own the memory it uses.
This commit is contained in:
parent
e5eaf4d222
commit
5b8cde66f1
|
@ -36,6 +36,23 @@ typedef struct {
|
|||
|
||||
static HRESULT compile_expression(compile_ctx_t*,expression_t*);
|
||||
|
||||
static inline void *compiler_alloc(vbscode_t *vbscode, size_t size)
|
||||
{
|
||||
return vbsheap_alloc(&vbscode->heap, size);
|
||||
}
|
||||
|
||||
static WCHAR *compiler_alloc_string(vbscode_t *vbscode, const WCHAR *str)
|
||||
{
|
||||
size_t size;
|
||||
WCHAR *ret;
|
||||
|
||||
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||
ret = compiler_alloc(vbscode, size);
|
||||
if(ret)
|
||||
memcpy(ret, str, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline instr_t *instr_ptr(compile_ctx_t *ctx, unsigned id)
|
||||
{
|
||||
assert(id < ctx->instr_cnt);
|
||||
|
@ -75,13 +92,18 @@ static HRESULT push_instr_int(compile_ctx_t *ctx, vbsop_t op, LONG arg)
|
|||
|
||||
static HRESULT push_instr_str(compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
|
||||
{
|
||||
unsigned ret;
|
||||
unsigned instr;
|
||||
WCHAR *str;
|
||||
|
||||
ret = push_instr(ctx, op);
|
||||
if(ret == -1)
|
||||
str = compiler_alloc_string(ctx->code, arg);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
instr_ptr(ctx, ret)->arg1.str = arg;
|
||||
instr = push_instr(ctx, op);
|
||||
if(instr == -1)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
instr_ptr(ctx, instr)->arg1.str = str;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -263,6 +285,8 @@ void release_vbscode(vbscode_t *code)
|
|||
for(i=0; i < code->bstr_cnt; i++)
|
||||
SysFreeString(code->bstr_pool[i]);
|
||||
|
||||
vbsheap_free(&code->heap);
|
||||
|
||||
heap_free(code->bstr_pool);
|
||||
heap_free(code->source);
|
||||
heap_free(code->instrs);
|
||||
|
@ -291,6 +315,7 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
|
|||
|
||||
ctx->instr_cnt = 0;
|
||||
ctx->instr_size = 32;
|
||||
vbsheap_init(&ret->heap);
|
||||
|
||||
ret->option_explicit = ctx->parser.option_explicit;
|
||||
|
||||
|
|
|
@ -31,6 +31,18 @@
|
|||
#include "wine/list.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
typedef struct {
|
||||
void **blocks;
|
||||
DWORD block_cnt;
|
||||
DWORD last_block;
|
||||
DWORD offset;
|
||||
struct list custom_blocks;
|
||||
} vbsheap_t;
|
||||
|
||||
void vbsheap_init(vbsheap_t*) DECLSPEC_HIDDEN;
|
||||
void *vbsheap_alloc(vbsheap_t*,size_t) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN;
|
||||
void vbsheap_free(vbsheap_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct _function_t function_t;
|
||||
typedef struct _vbscode_t vbscode_t;
|
||||
typedef struct _script_ctx_t script_ctx_t;
|
||||
|
@ -122,6 +134,7 @@ struct _vbscode_t {
|
|||
BSTR *bstr_pool;
|
||||
unsigned bstr_pool_size;
|
||||
unsigned bstr_cnt;
|
||||
vbsheap_t heap;
|
||||
|
||||
struct list entry;
|
||||
};
|
||||
|
|
|
@ -31,6 +31,89 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
|||
|
||||
static HINSTANCE vbscript_hinstance;
|
||||
|
||||
#define MIN_BLOCK_SIZE 128
|
||||
|
||||
static inline DWORD block_size(DWORD block)
|
||||
{
|
||||
return MIN_BLOCK_SIZE << block;
|
||||
}
|
||||
|
||||
void vbsheap_init(vbsheap_t *heap)
|
||||
{
|
||||
memset(heap, 0, sizeof(*heap));
|
||||
list_init(&heap->custom_blocks);
|
||||
}
|
||||
|
||||
void *vbsheap_alloc(vbsheap_t *heap, size_t size)
|
||||
{
|
||||
struct list *list;
|
||||
void *tmp;
|
||||
|
||||
size = (size+3)&~3;
|
||||
|
||||
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;
|
||||
heap->blocks[heap->block_cnt] = heap_alloc(block_size(heap->block_cnt));
|
||||
if(!heap->blocks[heap->block_cnt])
|
||||
return NULL;
|
||||
|
||||
heap->block_cnt++;
|
||||
}
|
||||
|
||||
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 vbsheap_free(vbsheap_t *heap)
|
||||
{
|
||||
struct list *iter;
|
||||
DWORD i;
|
||||
|
||||
while((iter = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
|
||||
list_remove(iter);
|
||||
heap_free(iter);
|
||||
}
|
||||
|
||||
for(i=0; i < heap->block_cnt; i++)
|
||||
heap_free(heap->blocks[i]);
|
||||
heap_free(heap->blocks);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
|
|
Loading…
Reference in New Issue