Jacek Caban : jscript: Use wine_rb_tree to store local variables in compiler_ctx_t.
Alexandre Julliard
julliard at winehq.org
Wed Sep 21 10:14:50 CDT 2016
Module: wine
Branch: master
Commit: 0f21353ac073d143e9158665115db1d9e17eca09
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0f21353ac073d143e9158665115db1d9e17eca09
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Sep 20 21:16:02 2016 +0200
jscript: Use wine_rb_tree to store local variables in compiler_ctx_t.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/jscript/compile.c | 77 +++++++++++++++++++++++++-------------------------
1 file changed, 38 insertions(+), 39 deletions(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index a1b2207..fe3e043 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -23,6 +23,7 @@
#include "engine.h"
#include "parser.h"
+#include "wine/rbtree.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
@@ -42,6 +43,12 @@ typedef struct _statement_ctx_t {
} 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;
-
- 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;
- }
+ function_local_t *local;
- 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;
- }
- }
+ local = heap_pool_alloc(&ctx->heap, sizeof(*local));
+ if(!local)
+ return FALSE;
- 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;
More information about the wine-cvs
mailing list