Jacek Caban : jscript: Added bytecode version of with statement.

Alexandre Julliard julliard at winehq.org
Tue Dec 27 11:27:56 CST 2011


Module: wine
Branch: master
Commit: abffe88e1991ec90a368f8a67142ae57c12cc46f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=abffe88e1991ec90a368f8a67142ae57c12cc46f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Dec 27 11:16:26 2011 +0100

jscript: Added bytecode version of with statement.

---

 dlls/jscript/compile.c |   36 ++++++++++++++++++++++++++++++++++++
 dlls/jscript/dispex.c  |    5 +++++
 dlls/jscript/engine.c  |   42 ++++++++++++++++++++++++++++++++++++++++++
 dlls/jscript/engine.h  |    2 ++
 dlls/jscript/jscript.h |    1 +
 dlls/jscript/parser.y  |    2 +-
 6 files changed, 87 insertions(+), 1 deletions(-)

diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index 663edf0..c2179d3 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -1097,6 +1097,40 @@ static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
     return S_OK;
 }
 
+/* ECMA-262 3rd Edition    12.10 */
+static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat)
+{
+    unsigned off_backup;
+    BOOL prev_no_fallback;
+    HRESULT hres;
+
+    off_backup = ctx->code_off;
+
+    hres = compile_expression(ctx, stat->expr);
+    if(FAILED(hres))
+        return hres;
+
+    if(push_instr(ctx, OP_push_scope) == -1)
+        return E_OUTOFMEMORY;
+
+    prev_no_fallback = ctx->no_fallback;
+    ctx->no_fallback = TRUE;
+    hres = compile_statement(ctx, stat->statement);
+    ctx->no_fallback = prev_no_fallback;
+    if(hres == E_NOTIMPL) {
+        ctx->code_off = off_backup;
+        stat->stat.eval = with_statement_eval;
+        return compile_interp_fallback(ctx, &stat->stat);
+    }
+    if(FAILED(hres))
+        return hres;
+
+    if(push_instr(ctx, OP_pop_scope) == -1)
+        return E_OUTOFMEMORY;
+
+    return S_OK;
+}
+
 static HRESULT compile_statement(compiler_ctx_t *ctx, statement_t *stat)
 {
     switch(stat->type) {
@@ -1114,6 +1148,8 @@ static HRESULT compile_statement(compiler_ctx_t *ctx, statement_t *stat)
         return compile_var_statement(ctx, (var_statement_t*)stat);
     case STAT_WHILE:
         return compile_while_statement(ctx, (while_statement_t*)stat);
+    case STAT_WITH:
+        return compile_with_statement(ctx, (with_statement_t*)stat);
     default:
         return compile_interp_fallback(ctx, stat);
     }
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index f2d2992..0b73073 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -837,6 +837,11 @@ jsdisp_t *as_jsdisp(IDispatch *disp)
     return impl_from_IDispatchEx((IDispatchEx*)disp);
 }
 
+jsdisp_t *to_jsdisp(IDispatch *disp)
+{
+    return disp->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl ? impl_from_IDispatchEx((IDispatchEx*)disp) : NULL;
+}
+
 HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
 {
     TRACE("%p (%p)\n", dispex, prototype);
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 9f4a5a7..af15a94 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -1029,6 +1029,43 @@ HRESULT with_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t
     return hres;
 }
 
+/* ECMA-262 3rd Edition    12.10 */
+HRESULT interp_push_scope(exec_ctx_t *ctx)
+{
+    IDispatch *disp;
+    jsdisp_t *obj;
+    VARIANT *v;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    v = stack_pop(ctx);
+    hres = to_object(ctx->parser->script, v, &disp);
+    VariantClear(v);
+    if(FAILED(hres))
+        return hres;
+
+    obj = to_jsdisp(disp);
+    if(!obj) {
+        IDispatch_Release(disp);
+        FIXME("disp is not jsdisp\n");
+        return E_NOTIMPL;
+    }
+
+    hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain);
+    jsdisp_release(obj);
+    return hres;
+}
+
+/* ECMA-262 3rd Edition    12.10 */
+HRESULT interp_pop_scope(exec_ctx_t *ctx)
+{
+    TRACE("\n");
+
+    scope_pop(&ctx->scope_chain);
+    return S_OK;
+}
+
 /* ECMA-262 3rd Edition    12.12 */
 HRESULT labelled_statement_eval(script_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
 {
@@ -2955,6 +2992,7 @@ HRESULT compiled_statement_eval(script_ctx_t *ctx, statement_t *stat, return_typ
 {
     exec_ctx_t *exec_ctx = ctx->exec_ctx;
     unsigned prev_ip, prev_top;
+    scope_chain_t *prev_scope;
     return_type_t *prev_rt;
     jsexcept_t *prev_ei;
     jsop_t op;
@@ -2970,6 +3008,7 @@ HRESULT compiled_statement_eval(script_ctx_t *ctx, statement_t *stat, return_typ
 
     prev_rt = exec_ctx->rt;
     prev_top = exec_ctx->top;
+    prev_scope = exec_ctx->scope_chain;
     prev_ip = exec_ctx->ip;
     prev_ei = exec_ctx->ei;
     exec_ctx->ip = stat->instr_off;
@@ -2990,10 +3029,13 @@ HRESULT compiled_statement_eval(script_ctx_t *ctx, statement_t *stat, return_typ
 
     if(FAILED(hres)) {
         stack_popn(exec_ctx, exec_ctx->top-prev_top);
+        while(exec_ctx->scope_chain != prev_scope)
+            scope_pop(&exec_ctx->scope_chain);
         return hres;
     }
 
     assert(exec_ctx->top == prev_top+1 || exec_ctx->top == prev_top);
+    assert(exec_ctx->scope_chain == prev_scope);
 
     if(exec_ctx->top == prev_top)
         V_VT(ret) = VT_EMPTY;
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 2f0ba53..1ca6630 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -87,8 +87,10 @@ typedef struct _func_stack {
     X(obj_prop,   1, ARG_BSTR,   0)        \
     X(or,         1, 0,0)                  \
     X(pop,        1, 0,0)                  \
+    X(pop_scope,  1, 0,0)                  \
     X(postinc,    1, ARG_INT,    0)        \
     X(preinc,     1, ARG_INT,    0)        \
+    X(push_scope, 1, 0,0)                  \
     X(regexp,     1, ARG_STR,    ARG_INT)  \
     X(rshift,     1, 0,0)                  \
     X(rshift2,    1, 0,0)                  \
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index bd00cbe..8b1aa2d 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -190,6 +190,7 @@ static inline IDispatch *to_disp(jsdisp_t *jsdisp)
 }
 
 jsdisp_t *as_jsdisp(IDispatch*);
+jsdisp_t *to_jsdisp(IDispatch*);
 
 static inline void jsdisp_addref(jsdisp_t *jsdisp)
 {
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index 008ada2..578ae23 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -851,7 +851,7 @@ static const statement_eval_t stat_eval_table[] = {
     try_statement_eval,
     compiled_statement_eval,
     compiled_statement_eval,
-    with_statement_eval
+    compiled_statement_eval
 };
 
 static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size)




More information about the wine-cvs mailing list