jscript: Move function call implementation into vtbl.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4960f9e338
commit
5c5397d1ef
|
@ -40,6 +40,7 @@ typedef struct {
|
||||||
} FunctionInstance;
|
} FunctionInstance;
|
||||||
|
|
||||||
struct _function_vtbl_t {
|
struct _function_vtbl_t {
|
||||||
|
HRESULT (*call)(script_ctx_t*,FunctionInstance*,IDispatch*,unsigned,unsigned,jsval_t*,jsval_t*);
|
||||||
HRESULT (*toString)(FunctionInstance*,jsstr_t**);
|
HRESULT (*toString)(FunctionInstance*,jsstr_t**);
|
||||||
void (*destructor)(FunctionInstance*);
|
void (*destructor)(FunctionInstance*);
|
||||||
};
|
};
|
||||||
|
@ -243,69 +244,8 @@ void detach_arguments_object(jsdisp_t *args_disp)
|
||||||
jsdisp_release(frame->arguments_obj);
|
jsdisp_release(frame->arguments_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv,
|
|
||||||
BOOL is_constructor, BOOL caller_execs_source, jsval_t *r)
|
|
||||||
{
|
|
||||||
jsdisp_t *var_disp;
|
|
||||||
DWORD exec_flags = 0;
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
if(ctx->state == SCRIPTSTATE_UNINITIALIZED || ctx->state == SCRIPTSTATE_CLOSED) {
|
|
||||||
WARN("Script engine state does not allow running code.\n");
|
|
||||||
return E_UNEXPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!function->func_code) {
|
|
||||||
FIXME("no source\n");
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hres = create_dispex(ctx, NULL, NULL, &var_disp);
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
|
|
||||||
if(caller_execs_source)
|
|
||||||
exec_flags |= EXEC_RETURN_TO_INTERP;
|
|
||||||
if(is_constructor)
|
|
||||||
exec_flags |= EXEC_CONSTRUCTOR;
|
|
||||||
hres = exec_source(ctx, exec_flags, function->code, function->func_code, function->scope_chain, this_obj,
|
|
||||||
&function->dispex, var_disp, argc, argv, r);
|
|
||||||
|
|
||||||
jsdisp_release(var_disp);
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT invoke_value_proc(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_disp, WORD flags,
|
|
||||||
unsigned argc, jsval_t *argv, jsval_t *r)
|
|
||||||
{
|
|
||||||
vdisp_t vthis;
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
if(this_disp)
|
|
||||||
set_disp(&vthis, this_disp);
|
|
||||||
else if(ctx->host_global)
|
|
||||||
set_disp(&vthis, ctx->host_global);
|
|
||||||
else
|
|
||||||
set_jsdisp(&vthis, ctx->global);
|
|
||||||
|
|
||||||
hres = function->value_proc(ctx, &vthis, flags, argc, argv, r);
|
|
||||||
|
|
||||||
vdisp_release(&vthis);
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj,
|
|
||||||
unsigned argc, jsval_t *argv, BOOL caller_execs_source, jsval_t *r)
|
|
||||||
{
|
|
||||||
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, FALSE, caller_execs_source, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||||
{
|
{
|
||||||
const BOOL caller_execs_source = (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0;
|
|
||||||
FunctionInstance *function;
|
FunctionInstance *function;
|
||||||
|
|
||||||
TRACE("func %p this %p\n", func_this, jsthis);
|
TRACE("func %p this %p\n", func_this, jsthis);
|
||||||
|
@ -313,25 +253,7 @@ HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsi
|
||||||
assert(is_class(func_this, JSCLASS_FUNCTION));
|
assert(is_class(func_this, JSCLASS_FUNCTION));
|
||||||
function = function_from_jsdisp(func_this);
|
function = function_from_jsdisp(func_this);
|
||||||
|
|
||||||
flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
|
return function->vtbl->call(function->dispex.ctx, function, jsthis, flags, argc, argv, r);
|
||||||
if(function->value_proc)
|
|
||||||
return invoke_value_proc(function->dispex.ctx, function, jsthis, flags, 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, caller_execs_source, r);
|
|
||||||
jsdisp_release(this_obj);
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(flags == DISPATCH_METHOD);
|
|
||||||
return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, FALSE, caller_execs_source, r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
|
static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
|
||||||
|
@ -445,7 +367,7 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
|
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
if(function) {
|
if(function) {
|
||||||
hres = call_function(ctx, function, this_obj, cnt, args, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r);
|
hres = function->vtbl->call(ctx, function, this_obj, flags, cnt, args, r);
|
||||||
}else {
|
}else {
|
||||||
jsval_t res;
|
jsval_t res;
|
||||||
hres = disp_call_value(ctx, jsthis->u.disp, this_obj, DISPATCH_METHOD, cnt, args, &res);
|
hres = disp_call_value(ctx, jsthis->u.disp, this_obj, DISPATCH_METHOD, cnt, args, &res);
|
||||||
|
@ -489,7 +411,7 @@ static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
||||||
cnt = argc-1;
|
cnt = argc-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = call_function(ctx, function, this_obj, cnt, argv+1, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r);
|
hres = function->vtbl->call(ctx, function, this_obj, flags, cnt, argv + 1, r);
|
||||||
|
|
||||||
if(this_obj)
|
if(this_obj)
|
||||||
IDispatch_Release(this_obj);
|
IDispatch_Release(this_obj);
|
||||||
|
@ -509,9 +431,7 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
function = function_from_jsdisp(jsthis->u.jsdisp);
|
function = function_from_jsdisp(jsthis->u.jsdisp);
|
||||||
|
return function->vtbl->call(ctx, function, NULL, flags, argc, argv, r);
|
||||||
assert(function->value_proc != NULL);
|
|
||||||
return invoke_value_proc(ctx, function, NULL, flags, argc, argv, r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
|
HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
|
||||||
|
@ -621,6 +541,25 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT NativeFunction_call(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_disp, unsigned flags,
|
||||||
|
unsigned argc, jsval_t *argv, jsval_t *r)
|
||||||
|
{
|
||||||
|
vdisp_t vthis;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
if(this_disp)
|
||||||
|
set_disp(&vthis, this_disp);
|
||||||
|
else if(ctx->host_global)
|
||||||
|
set_disp(&vthis, ctx->host_global);
|
||||||
|
else
|
||||||
|
set_jsdisp(&vthis, ctx->global);
|
||||||
|
|
||||||
|
hres = function->value_proc(ctx, &vthis, flags & ~DISPATCH_JSCRIPT_INTERNAL_MASK, argc, argv, r);
|
||||||
|
|
||||||
|
vdisp_release(&vthis);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT NativeFunction_toString(FunctionInstance *function, jsstr_t **ret)
|
static HRESULT NativeFunction_toString(FunctionInstance *function, jsstr_t **ret)
|
||||||
{
|
{
|
||||||
DWORD name_len;
|
DWORD name_len;
|
||||||
|
@ -651,6 +590,7 @@ static void NativeFunction_destructor(FunctionInstance *function)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const function_vtbl_t NativeFunctionVtbl = {
|
static const function_vtbl_t NativeFunctionVtbl = {
|
||||||
|
NativeFunction_call,
|
||||||
NativeFunction_toString,
|
NativeFunction_toString,
|
||||||
NativeFunction_destructor
|
NativeFunction_destructor
|
||||||
};
|
};
|
||||||
|
@ -710,6 +650,43 @@ HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_pro
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT InterpretedFunction_call(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned flags,
|
||||||
|
unsigned argc, jsval_t *argv, jsval_t *r)
|
||||||
|
{
|
||||||
|
jsdisp_t *var_disp, *new_obj = NULL;
|
||||||
|
DWORD exec_flags = 0;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("%p\n", function);
|
||||||
|
|
||||||
|
if(ctx->state == SCRIPTSTATE_UNINITIALIZED || ctx->state == SCRIPTSTATE_CLOSED) {
|
||||||
|
WARN("Script engine state does not allow running code.\n");
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags & DISPATCH_CONSTRUCT) {
|
||||||
|
hres = create_object(ctx, &function->dispex, &new_obj);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
this_obj = to_disp(new_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE)
|
||||||
|
exec_flags |= EXEC_RETURN_TO_INTERP;
|
||||||
|
if(flags & DISPATCH_CONSTRUCT)
|
||||||
|
exec_flags |= EXEC_CONSTRUCTOR;
|
||||||
|
|
||||||
|
hres = create_dispex(ctx, NULL, NULL, &var_disp);
|
||||||
|
if(SUCCEEDED(hres))
|
||||||
|
hres = exec_source(ctx, exec_flags, function->code, function->func_code, function->scope_chain, this_obj,
|
||||||
|
&function->dispex, var_disp, argc, argv, r);
|
||||||
|
if(new_obj)
|
||||||
|
jsdisp_release(new_obj);
|
||||||
|
|
||||||
|
jsdisp_release(var_disp);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT InterpretedFunction_toString(FunctionInstance *function, jsstr_t **ret)
|
static HRESULT InterpretedFunction_toString(FunctionInstance *function, jsstr_t **ret)
|
||||||
{
|
{
|
||||||
*ret = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
|
*ret = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
|
||||||
|
@ -724,6 +701,7 @@ static void InterpretedFunction_destructor(FunctionInstance *function)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const function_vtbl_t InterpretedFunctionVtbl = {
|
static const function_vtbl_t InterpretedFunctionVtbl = {
|
||||||
|
InterpretedFunction_call,
|
||||||
InterpretedFunction_toString,
|
InterpretedFunction_toString,
|
||||||
InterpretedFunction_destructor
|
InterpretedFunction_destructor
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue