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