Jacek Caban : jscript: Moved constructor return logic to interpreter.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Mar 29 08:53:21 CDT 2016


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar 28 17:49:53 2016 +0200

jscript: Moved constructor return logic to interpreter.

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

---

 dlls/jscript/engine.c   |  6 ++++++
 dlls/jscript/engine.h   |  1 +
 dlls/jscript/function.c | 52 ++++++++++++++++++-------------------------------
 3 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 8dab026..4d7c175 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -2331,6 +2331,12 @@ static HRESULT interp_ret(script_ctx_t *ctx)
     if(clear_ret)
         jsval_release(steal_ret(frame));
 
+    if((frame->flags & EXEC_CONSTRUCTOR) && !is_object_instance(frame->ret)) {
+        jsval_release(frame->ret);
+        IDispatch_AddRef(frame->this_obj);
+        frame->ret = jsval_disp(frame->this_obj);
+    }
+
     jmp_abs(ctx, -1);
     return S_OK;
 }
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 7044858..4915b60 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -212,6 +212,7 @@ typedef struct _call_frame_t {
 } call_frame_t;
 
 #define EXEC_GLOBAL            0x0001
+#define EXEC_CONSTRUCTOR       0x0002
 
 HRESULT exec_source(script_ctx_t*,DWORD,bytecode_t*,function_code_t*,scope_chain_t*,IDispatch*,jsdisp_t*,jsval_t*) DECLSPEC_HIDDEN;
 HRESULT create_source_function(script_ctx_t*,bytecode_t*,function_code_t*,scope_chain_t*,jsdisp_t**) DECLSPEC_HIDDEN;
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index c677d94..bd85fda 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -203,7 +203,7 @@ static HRESULT create_var_disp(script_ctx_t *ctx, FunctionInstance *function, un
 }
 
 static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv,
-        jsval_t *r)
+        BOOL is_constructor, jsval_t *r)
 {
     jsdisp_t *var_disp, *arg_disp;
     scope_chain_t *scope;
@@ -238,11 +238,14 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
 
     hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
     if(SUCCEEDED(hres)) {
+        DWORD exec_flags = 0;
         jsdisp_t *prev_args;
 
+        if(is_constructor)
+            exec_flags |= EXEC_CONSTRUCTOR;
         prev_args = function->arguments;
         function->arguments = arg_disp;
-        hres = exec_source(ctx, 0, function->code, function->func_code, scope, this_obj, var_disp, r);
+        hres = exec_source(ctx, exec_flags, function->code, function->func_code, scope, this_obj, var_disp, r);
         function->arguments = prev_args;
 
         scope_release(scope);
@@ -257,33 +260,6 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
     return hres;
 }
 
-static HRESULT invoke_constructor(script_ctx_t *ctx, FunctionInstance *function, unsigned argc, jsval_t *argv,
-        jsval_t *r)
-{
-    jsdisp_t *this_obj;
-    jsval_t var;
-    HRESULT hres;
-
-    hres = create_object(ctx, &function->dispex, &this_obj);
-    if(FAILED(hres))
-        return hres;
-
-    hres = invoke_source(ctx, function, to_disp(this_obj), argc, argv, &var);
-    if(FAILED(hres)) {
-        jsdisp_release(this_obj);
-        return hres;
-    }
-
-    if(is_object_instance(var)) {
-        jsdisp_release(this_obj);
-        *r = var;
-    }else {
-        jsval_release(var);
-        *r = jsval_obj(this_obj);
-    }
-    return S_OK;
-}
-
 static HRESULT invoke_value_proc(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_disp, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
@@ -309,7 +285,7 @@ static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDis
     if(function->value_proc)
         return invoke_value_proc(ctx, function, this_obj, DISPATCH_METHOD, argc, argv, r);
 
-    return invoke_source(ctx, function, this_obj, argc, argv, r);
+    return invoke_source(ctx, function, this_obj, argc, argv, FALSE, r);
 }
 
 static HRESULT function_to_string(FunctionInstance *function, jsstr_t **ret)
@@ -354,11 +330,21 @@ HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsi
     if(function->value_proc)
         return invoke_value_proc(function->dispex.ctx, function, jsthis, flags, argc, argv, r);
 
-    if(flags == DISPATCH_CONSTRUCT)
-        return invoke_constructor(function->dispex.ctx, function, argc, argv, r);
+    if(flags == DISPATCH_CONSTRUCT) {
+        jsdisp_t *this_obj;
+        HRESULT hres;
+
+        hres = create_object(function->dispex.ctx, &function->dispex, &this_obj);
+        if(FAILED(hres))
+            return hres;
+
+        hres = invoke_source(function->dispex.ctx, function, to_disp(this_obj), argc, argv, TRUE, r);
+        jsdisp_release(this_obj);
+        return hres;
+    }
 
     assert(flags == DISPATCH_METHOD);
-    return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, r);
+    return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, FALSE, r);
 }
 
 static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)




More information about the wine-cvs mailing list