Jacek Caban : jscript: Use global accumulator for storing function call results.

Alexandre Julliard julliard at winehq.org
Tue Jun 12 17:36:03 CDT 2018


Module: wine
Branch: master
Commit: 5a90acf59cb80ab232f90d2955a956166d983835
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5a90acf59cb80ab232f90d2955a956166d983835

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jun 12 14:04:11 2018 +0200

jscript: Use global accumulator for storing function call results.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/compile.c     |  4 ++--
 dlls/jscript/engine.c      | 31 ++++++++++++++-----------------
 dlls/jscript/engine.h      |  2 +-
 dlls/jscript/jscript.c     |  2 ++
 dlls/jscript/jscript.h     |  1 +
 dlls/jscript/tests/lang.js | 21 +++++++++++++++++++++
 6 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index 6e6be91..5e844ee 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -609,7 +609,7 @@ static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *ex
     if(FAILED(hres))
         return hres;
 
-    return push_instr(ctx, OP_push_ret) ? S_OK : E_OUTOFMEMORY;
+    return push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
 }
 
 static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
@@ -651,7 +651,7 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e
     if(FAILED(hres))
         return hres;
 
-    return !emit_ret || push_instr(ctx, OP_push_ret) ? S_OK : E_OUTOFMEMORY;
+    return !emit_ret || push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
 }
 
 static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index d7a5a46..bd4edda 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -385,9 +385,10 @@ static inline jsval_t steal_ret(call_frame_t *frame)
     return r;
 }
 
-static inline void clear_ret(call_frame_t *frame)
+static inline void clear_acc(script_ctx_t *ctx)
 {
-    jsval_release(steal_ret(frame));
+    jsval_release(ctx->acc);
+    ctx->acc = jsval_undefined();
 }
 
 static HRESULT scope_push(scope_chain_t *scope, jsdisp_t *jsobj, IDispatch *obj, scope_chain_t **ret)
@@ -1155,7 +1156,6 @@ static HRESULT interp_refval(script_ctx_t *ctx)
 static HRESULT interp_new(script_ctx_t *ctx)
 {
     const unsigned argc = get_op_uint(ctx, 0);
-    call_frame_t *frame = ctx->call_ctx;
     jsval_t constr;
 
     TRACE("%d\n", argc);
@@ -1171,9 +1171,9 @@ static HRESULT interp_new(script_ctx_t *ctx)
     else if(!get_object(constr))
         return throw_type_error(ctx, JS_E_INVALID_PROPERTY, NULL);
 
-    clear_ret(frame);
+    clear_acc(ctx);
     return disp_call_value(ctx, get_object(constr), NULL, DISPATCH_CONSTRUCT | DISPATCH_JSCRIPT_CALLEREXECSSOURCE,
-                           argc, stack_args(ctx, argc), &frame->ret);
+                           argc, stack_args(ctx, argc), &ctx->acc);
 }
 
 /* ECMA-262 3rd Edition    11.2.3 */
@@ -1181,7 +1181,6 @@ static HRESULT interp_call(script_ctx_t *ctx)
 {
     const unsigned argn = get_op_uint(ctx, 0);
     const int do_ret = get_op_int(ctx, 1);
-    call_frame_t *frame = ctx->call_ctx;
     jsval_t obj;
 
     TRACE("%d %d\n", argn, do_ret);
@@ -1190,9 +1189,9 @@ static HRESULT interp_call(script_ctx_t *ctx)
     if(!is_object_instance(obj))
         return throw_type_error(ctx, JS_E_INVALID_PROPERTY, NULL);
 
-    clear_ret(frame);
+    clear_acc(ctx);
     return disp_call_value(ctx, get_object(obj), NULL, DISPATCH_METHOD | DISPATCH_JSCRIPT_CALLEREXECSSOURCE,
-                           argn, stack_args(ctx, argn), do_ret ? &frame->ret : NULL);
+                           argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL);
 }
 
 /* ECMA-262 3rd Edition    11.2.3 */
@@ -1200,7 +1199,6 @@ static HRESULT interp_call_member(script_ctx_t *ctx)
 {
     const unsigned argn = get_op_uint(ctx, 0);
     const int do_ret = get_op_int(ctx, 1);
-    call_frame_t *frame = ctx->call_ctx;
     exprval_t ref;
 
     TRACE("%d %d\n", argn, do_ret);
@@ -1208,9 +1206,9 @@ static HRESULT interp_call_member(script_ctx_t *ctx)
     if(!stack_topn_exprval(ctx, argn, &ref))
         return throw_type_error(ctx, ref.u.hres, NULL);
 
-    clear_ret(frame);
+    clear_acc(ctx);
     return exprval_call(ctx, &ref, DISPATCH_METHOD | DISPATCH_JSCRIPT_CALLEREXECSSOURCE,
-            argn, stack_args(ctx, argn), do_ret ? &frame->ret : NULL);
+            argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL);
 }
 
 /* ECMA-262 3rd Edition    11.1.1 */
@@ -2600,16 +2598,15 @@ static HRESULT interp_setret(script_ctx_t *ctx)
     return S_OK;
 }
 
-static HRESULT interp_push_ret(script_ctx_t *ctx)
+static HRESULT interp_push_acc(script_ctx_t *ctx)
 {
-    call_frame_t *frame = ctx->call_ctx;
     HRESULT hres;
 
     TRACE("\n");
 
-    hres = stack_push(ctx, frame->ret);
+    hres = stack_push(ctx, ctx->acc);
     if(SUCCEEDED(hres))
-        frame->ret = jsval_undefined();
+        ctx->acc = jsval_undefined();
     return hres;
 }
 
@@ -2796,8 +2793,8 @@ static HRESULT enter_bytecode(script_ctx_t *ctx, jsval_t *r)
             assert(frame->scope == frame->base_scope);
 
             if(return_to_interp) {
-                clear_ret(frame->prev_frame);
-                frame->prev_frame->ret = steal_ret(frame);
+                jsval_release(ctx->acc);
+                ctx->acc = steal_ret(frame);
             }else if(r) {
                 *r = steal_ret(frame);
             }
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 31f6b1c..d3fd3d77 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -73,8 +73,8 @@
     X(pop_scope,  1, 0,0)                  \
     X(postinc,    1, ARG_INT,    0)        \
     X(preinc,     1, ARG_INT,    0)        \
+    X(push_acc,   1, 0,0)                  \
     X(push_except,1, ARG_ADDR,   ARG_UINT) \
-    X(push_ret,   1, 0,0)                  \
     X(push_scope, 1, 0,0)                  \
     X(regexp,     1, ARG_STR,    ARG_UINT) \
     X(rshift,     1, 0,0)                  \
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c
index 15d81d2..75eef39 100644
--- a/dlls/jscript/jscript.c
+++ b/dlls/jscript/jscript.c
@@ -69,6 +69,7 @@ void script_release(script_ctx_t *ctx)
     if(--ctx->ref)
         return;
 
+    jsval_release(ctx->acc);
     clear_ei(ctx);
     if(ctx->cc)
         release_cc(ctx->cc);
@@ -715,6 +716,7 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
     ctx->version = This->version;
     ctx->html_mode = This->html_mode;
     ctx->ei.val = jsval_undefined();
+    ctx->acc = jsval_undefined();
     heap_pool_init(&ctx->tmp_heap);
 
     hres = create_jscaller(ctx);
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 1cb6d15..2af5b59 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -424,6 +424,7 @@ struct _script_ctx_t {
     jsval_t *stack;
     unsigned stack_size;
     unsigned stack_top;
+    jsval_t acc;
 
     jsstr_t *last_match;
     match_result_t match_parens[9];
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index e6ff4dd..badb6a8 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -1146,6 +1146,27 @@ case 3:
     })();
     expect(ret, "ret");
     expect(x, "try,try2,finally2,finally,ret");
+
+    ret = (function() {
+        try {
+            return "try";
+            unreachable();
+        }catch(e) {
+            unreachable();
+        }finally {
+            new Object();
+            var tmp = (function() {
+                var s = new String();
+                try {
+                    s.length;
+                }finally {
+                    return 1;
+                }
+            })();
+        }
+        unreachable();
+    })();
+    expect(ret, "try");
 })();
 
 tmp = eval("1");




More information about the wine-cvs mailing list