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