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 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)
|
static inline instr_t *instr_ptr(compile_ctx_t *ctx, unsigned id)
|
||||||
{
|
{
|
||||||
assert(id < ctx->instr_cnt);
|
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)
|
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);
|
str = compiler_alloc_string(ctx->code, arg);
|
||||||
if(ret == -1)
|
if(!str)
|
||||||
return E_OUTOFMEMORY;
|
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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +285,8 @@ void release_vbscode(vbscode_t *code)
|
||||||
for(i=0; i < code->bstr_cnt; i++)
|
for(i=0; i < code->bstr_cnt; i++)
|
||||||
SysFreeString(code->bstr_pool[i]);
|
SysFreeString(code->bstr_pool[i]);
|
||||||
|
|
||||||
|
vbsheap_free(&code->heap);
|
||||||
|
|
||||||
heap_free(code->bstr_pool);
|
heap_free(code->bstr_pool);
|
||||||
heap_free(code->source);
|
heap_free(code->source);
|
||||||
heap_free(code->instrs);
|
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_cnt = 0;
|
||||||
ctx->instr_size = 32;
|
ctx->instr_size = 32;
|
||||||
|
vbsheap_init(&ret->heap);
|
||||||
|
|
||||||
ret->option_explicit = ctx->parser.option_explicit;
|
ret->option_explicit = ctx->parser.option_explicit;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,18 @@
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
#include "wine/unicode.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 _function_t function_t;
|
||||||
typedef struct _vbscode_t vbscode_t;
|
typedef struct _vbscode_t vbscode_t;
|
||||||
typedef struct _script_ctx_t script_ctx_t;
|
typedef struct _script_ctx_t script_ctx_t;
|
||||||
|
@ -122,6 +134,7 @@ struct _vbscode_t {
|
||||||
BSTR *bstr_pool;
|
BSTR *bstr_pool;
|
||||||
unsigned bstr_pool_size;
|
unsigned bstr_pool_size;
|
||||||
unsigned bstr_cnt;
|
unsigned bstr_cnt;
|
||||||
|
vbsheap_t heap;
|
||||||
|
|
||||||
struct list entry;
|
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;
|
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)
|
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
|
|
Loading…
Reference in New Issue