jscript: Use wine_rb_tree to store local variables in compiler_ctx_t.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Jacek Caban 2016-09-20 21:16:02 +02:00 committed by Alexandre Julliard
parent c16fb053d1
commit 0f21353ac0
1 changed files with 38 additions and 39 deletions

View File

@ -23,6 +23,7 @@
#include "engine.h"
#include "parser.h"
#include "wine/rbtree.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
@ -41,6 +42,12 @@ typedef struct _statement_ctx_t {
struct _statement_ctx_t *next;
} statement_ctx_t;
typedef struct {
struct wine_rb_entry entry;
BSTR name;
int ref;
} function_local_t;
typedef struct {
parser_ctx_t *parser;
bytecode_t *code;
@ -54,8 +61,7 @@ typedef struct {
unsigned labels_size;
unsigned labels_cnt;
local_ref_t *locals_buf;
unsigned locals_buf_size;
struct wine_rb_tree locals;
unsigned locals_cnt;
statement_ctx_t *stat_ctx;
@ -63,6 +69,8 @@ typedef struct {
function_expression_t *func_head;
function_expression_t *func_tail;
heap_pool_t heap;
} compiler_ctx_t;
static const struct {
@ -1812,42 +1820,29 @@ static HRESULT compile_statement(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx,
return hres;
}
static int local_cmp(const void *key, const void *ref)
static int function_local_cmp(const void *key, const struct wine_rb_entry *entry)
{
return strcmpW((const WCHAR*)key, ((const local_ref_t*)ref)->name);
function_local_t *local = WINE_RB_ENTRY_VALUE(entry, function_local_t, entry);
return strcmpW(key, local->name);
}
static inline local_ref_t *find_local(compiler_ctx_t *ctx, const WCHAR *name)
static inline function_local_t *find_local(compiler_ctx_t *ctx, const WCHAR *name)
{
return bsearch(name, ctx->locals_buf, ctx->locals_cnt, sizeof(*ctx->locals_buf), local_cmp);
struct wine_rb_entry *entry = wine_rb_get(&ctx->locals, name);
return entry ? WINE_RB_ENTRY_VALUE(entry, function_local_t, entry) : NULL;
}
static BOOL alloc_local(compiler_ctx_t *ctx, BSTR name, int ref)
{
unsigned i;
function_local_t *local;
if(!ctx->locals_buf_size) {
ctx->locals_buf = heap_alloc(4 * sizeof(*ctx->locals_buf));
if(!ctx->locals_buf)
return FALSE;
ctx->locals_buf_size = 4;
}else if(ctx->locals_buf_size == ctx->locals_cnt) {
local_ref_t *new_buf = heap_realloc(ctx->locals_buf, ctx->locals_buf_size * 2 * sizeof(*ctx->locals_buf));
if(!new_buf)
return FALSE;
ctx->locals_buf = new_buf;
ctx->locals_buf_size *= 2;
}
local = heap_pool_alloc(&ctx->heap, sizeof(*local));
if(!local)
return FALSE;
for(i = 0; i < ctx->locals_cnt; i++) {
if(strcmpW(ctx->locals_buf[i].name, name) > 0) {
memmove(ctx->locals_buf + i+1, ctx->locals_buf + i, (ctx->locals_cnt - i) * sizeof(*ctx->locals_buf));
break;
}
}
ctx->locals_buf[i].name = name;
ctx->locals_buf[i].ref = ref;
local->name = name;
local->ref = ref;
wine_rb_put(&ctx->locals, name, &local->entry);
ctx->locals_cnt++;
return TRUE;
}
@ -2264,7 +2259,8 @@ static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source,
BOOL from_eval, function_code_t *func)
{
function_expression_t *iter;
unsigned off, i, j;
function_local_t *local;
unsigned off, i;
HRESULT hres;
TRACE("\n");
@ -2273,6 +2269,7 @@ static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source,
ctx->from_eval = from_eval;
ctx->func = func;
ctx->locals_cnt = 0;
wine_rb_init(&ctx->locals, function_local_cmp);
if(func_expr) {
parameter_t *param_iter;
@ -2319,21 +2316,22 @@ static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source,
if(!func->locals)
return E_OUTOFMEMORY;
func->locals_cnt = ctx->locals_cnt;
memcpy(func->locals, ctx->locals_buf, func->locals_cnt * sizeof(*func->locals));
func->variables = compiler_alloc(ctx->code, func->var_cnt * sizeof(*func->variables));
if(!func->variables)
return E_OUTOFMEMORY;
for(i = 0, j = 0; i < func->locals_cnt; i++) {
if(func->locals[i].ref < 0)
continue; /* skip arguments */
func->variables[func->locals[i].ref].name = func->locals[i].name;
func->variables[func->locals[i].ref].func_id = -1;
j++;
i = 0;
WINE_RB_FOR_EACH_ENTRY(local, &ctx->locals, function_local_t, entry) {
func->locals[i].name = local->name;
func->locals[i].ref = local->ref;
if(local->ref >= 0) {
func->variables[local->ref].name = local->name;
func->variables[local->ref].func_id = -1;
}
i++;
}
assert(j == func->var_cnt);
assert(i == ctx->locals_cnt);
func->funcs = compiler_alloc(ctx->code, func->func_cnt * sizeof(*func->funcs));
if(!func->funcs)
@ -2476,9 +2474,10 @@ HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args,
return hres;
}
heap_pool_init(&compiler.heap);
hres = compile_function(&compiler, compiler.parser->source, NULL, from_eval, &compiler.code->global_code);
heap_pool_free(&compiler.heap);
parser_release(compiler.parser);
heap_free(compiler.locals_buf);
if(FAILED(hres)) {
release_bytecode(compiler.code);
return hres;