jscript: Store function arguments on JS stack and transfer them to variable object only when needed.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ba2e025b94
commit
5e4d3826ec
|
@ -267,13 +267,8 @@ HRESULT scope_push(scope_chain_t *scope, jsdisp_t *jsobj, IDispatch *obj, scope_
|
||||||
IDispatch_AddRef(obj);
|
IDispatch_AddRef(obj);
|
||||||
new_scope->jsobj = jsobj;
|
new_scope->jsobj = jsobj;
|
||||||
new_scope->obj = obj;
|
new_scope->obj = obj;
|
||||||
|
new_scope->frame = NULL;
|
||||||
if(scope) {
|
new_scope->next = scope ? scope_addref(scope) : NULL;
|
||||||
scope_addref(scope);
|
|
||||||
new_scope->next = scope;
|
|
||||||
}else {
|
|
||||||
new_scope->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = new_scope;
|
*ret = new_scope;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -427,6 +422,34 @@ static HRESULT equal2_values(jsval_t lval, jsval_t rval, BOOL *ret)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transfers local variables from stack to variable object.
|
||||||
|
* It's slow, so we want to avoid it as much as possible.
|
||||||
|
*/
|
||||||
|
HRESULT detach_variable_object(script_ctx_t *ctx, call_frame_t *frame)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
if(!frame->base_scope || !frame->base_scope->frame)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
TRACE("detaching %p\n", frame);
|
||||||
|
|
||||||
|
assert(frame == frame->base_scope->frame);
|
||||||
|
assert(frame->variable_obj == frame->base_scope->jsobj);
|
||||||
|
|
||||||
|
frame->base_scope->frame = NULL;
|
||||||
|
|
||||||
|
for(i = 0; i < frame->function->param_cnt; i++) {
|
||||||
|
hres = jsdisp_propput_name(frame->variable_obj, frame->function->params[i], ctx->stack[frame->arguments_off+i]);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
|
static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
|
||||||
{
|
{
|
||||||
named_item_t *item;
|
named_item_t *item;
|
||||||
|
@ -459,6 +482,11 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
|
||||||
|
|
||||||
if(ctx->call_ctx) {
|
if(ctx->call_ctx) {
|
||||||
for(scope = ctx->call_ctx->scope; scope; scope = scope->next) {
|
for(scope = ctx->call_ctx->scope; scope; scope = scope->next) {
|
||||||
|
if(scope->frame) {
|
||||||
|
hres = detach_variable_object(ctx, scope->frame);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
if(scope->jsobj)
|
if(scope->jsobj)
|
||||||
hres = jsdisp_get_id(scope->jsobj, identifier, fdexNameImplicit, &id);
|
hres = jsdisp_get_id(scope->jsobj, identifier, fdexNameImplicit, &id);
|
||||||
else
|
else
|
||||||
|
@ -2379,8 +2407,10 @@ OP_LIST
|
||||||
#undef X
|
#undef X
|
||||||
};
|
};
|
||||||
|
|
||||||
static void release_call_frame(call_frame_t *frame)
|
static void pop_call_frame(script_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
call_frame_t *frame = ctx->call_ctx;
|
||||||
|
|
||||||
if(frame->arguments_obj) {
|
if(frame->arguments_obj) {
|
||||||
/* Reset arguments value to cut the reference cycle. Note that since all activation contexts have
|
/* Reset arguments value to cut the reference cycle. Note that since all activation contexts have
|
||||||
* their own arguments property, it's impossible to use prototype's one during name lookup */
|
* their own arguments property, it's impossible to use prototype's one during name lookup */
|
||||||
|
@ -2388,14 +2418,28 @@ static void release_call_frame(call_frame_t *frame)
|
||||||
jsdisp_propput_name(frame->variable_obj, argumentsW, jsval_undefined());
|
jsdisp_propput_name(frame->variable_obj, argumentsW, jsval_undefined());
|
||||||
jsdisp_release(frame->arguments_obj);
|
jsdisp_release(frame->arguments_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(frame->scope) {
|
||||||
|
/* If current scope will be kept alive, we need to transfer local variables to its variable object. */
|
||||||
|
if(frame->scope->ref > 1) {
|
||||||
|
HRESULT hres = detach_variable_object(ctx, frame);
|
||||||
|
if(FAILED(hres))
|
||||||
|
ERR("Failed to detach variable object: %08x\n", hres);
|
||||||
|
}
|
||||||
|
scope_release(frame->scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->stack_base -= frame->pop_locals;
|
||||||
|
stack_popn(ctx, frame->pop_locals);
|
||||||
|
|
||||||
|
ctx->call_ctx = frame->prev_frame;
|
||||||
|
|
||||||
if(frame->function_instance)
|
if(frame->function_instance)
|
||||||
jsdisp_release(frame->function_instance);
|
jsdisp_release(frame->function_instance);
|
||||||
if(frame->variable_obj)
|
if(frame->variable_obj)
|
||||||
jsdisp_release(frame->variable_obj);
|
jsdisp_release(frame->variable_obj);
|
||||||
if(frame->this_obj)
|
if(frame->this_obj)
|
||||||
IDispatch_Release(frame->this_obj);
|
IDispatch_Release(frame->this_obj);
|
||||||
if(frame->scope)
|
|
||||||
scope_release(frame->scope);
|
|
||||||
jsval_release(frame->ret);
|
jsval_release(frame->ret);
|
||||||
release_bytecode(frame->bytecode);
|
release_bytecode(frame->bytecode);
|
||||||
heap_free(frame);
|
heap_free(frame);
|
||||||
|
@ -2417,9 +2461,8 @@ static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres)
|
||||||
|
|
||||||
stack_popn(ctx, ctx->stack_top-frame->stack_base);
|
stack_popn(ctx, ctx->stack_top-frame->stack_base);
|
||||||
|
|
||||||
ctx->call_ctx = frame->prev_frame;
|
|
||||||
flags = frame->flags;
|
flags = frame->flags;
|
||||||
release_call_frame(frame);
|
pop_call_frame(ctx);
|
||||||
if(!(flags & EXEC_RETURN_TO_INTERP))
|
if(!(flags & EXEC_RETURN_TO_INTERP))
|
||||||
return exception_hres;
|
return exception_hres;
|
||||||
}
|
}
|
||||||
|
@ -2492,14 +2535,13 @@ static HRESULT enter_bytecode(script_ctx_t *ctx, jsval_t *r)
|
||||||
assert(ctx->stack_top == frame->stack_base);
|
assert(ctx->stack_top == frame->stack_base);
|
||||||
assert(frame->scope == frame->base_scope);
|
assert(frame->scope == frame->base_scope);
|
||||||
|
|
||||||
ctx->call_ctx = frame->prev_frame;
|
|
||||||
if(return_to_interp) {
|
if(return_to_interp) {
|
||||||
clear_ret(ctx->call_ctx);
|
clear_ret(frame->prev_frame);
|
||||||
ctx->call_ctx->ret = steal_ret(frame);
|
frame->prev_frame->ret = steal_ret(frame);
|
||||||
}else if(r) {
|
}else if(r) {
|
||||||
*r = steal_ret(frame);
|
*r = steal_ret(frame);
|
||||||
}
|
}
|
||||||
release_call_frame(frame);
|
pop_call_frame(ctx);
|
||||||
if(!return_to_interp)
|
if(!return_to_interp)
|
||||||
break;
|
break;
|
||||||
}else {
|
}else {
|
||||||
|
@ -2547,8 +2589,41 @@ static HRESULT bind_event_target(script_ctx_t *ctx, function_code_t *func, jsdis
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT setup_scope(script_ctx_t *ctx, call_frame_t *frame, unsigned argc, jsval_t *argv)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
jsval_t v;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
frame->arguments_off = ctx->stack_top;
|
||||||
|
|
||||||
|
for(i = 0; i < argc; i++) {
|
||||||
|
hres = jsval_copy(argv[i], &v);
|
||||||
|
if(SUCCEEDED(hres))
|
||||||
|
hres = stack_push(ctx, v);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
stack_popn(ctx, i);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If fewer than declared arguments were passed, fill remaining with undefined value. */
|
||||||
|
for(; i < frame->function->param_cnt; i++) {
|
||||||
|
hres = stack_push(ctx, jsval_undefined());
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
stack_popn(ctx, i);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->pop_locals = i;
|
||||||
|
frame->base_scope->frame = frame;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, function_code_t *function, scope_chain_t *scope,
|
HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, function_code_t *function, scope_chain_t *scope,
|
||||||
IDispatch *this_obj, jsdisp_t *function_instance, jsdisp_t *variable_obj, jsdisp_t *arguments_obj, jsval_t *r)
|
IDispatch *this_obj, jsdisp_t *function_instance, jsdisp_t *variable_obj, unsigned argc, jsval_t *argv,
|
||||||
|
jsdisp_t *arguments_obj, jsval_t *r)
|
||||||
{
|
{
|
||||||
call_frame_t *frame;
|
call_frame_t *frame;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -2595,18 +2670,34 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ctx->call_ctx && (flags & EXEC_EVAL)) {
|
||||||
|
hres = detach_variable_object(ctx, ctx->call_ctx);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
frame = heap_alloc_zero(sizeof(*frame));
|
frame = heap_alloc_zero(sizeof(*frame));
|
||||||
if(!frame)
|
if(!frame)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
frame->bytecode = bytecode_addref(bytecode);
|
|
||||||
frame->function = function;
|
frame->function = function;
|
||||||
frame->ip = function->instr_off;
|
|
||||||
frame->stack_base = ctx->stack_top;
|
|
||||||
frame->ret = jsval_undefined();
|
frame->ret = jsval_undefined();
|
||||||
if(scope)
|
|
||||||
|
if(scope) {
|
||||||
frame->base_scope = frame->scope = scope_addref(scope);
|
frame->base_scope = frame->scope = scope_addref(scope);
|
||||||
|
|
||||||
|
if(!(flags & (EXEC_GLOBAL|EXEC_EVAL))) {
|
||||||
|
hres = setup_scope(ctx, frame, argc, argv);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
heap_free(frame);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->bytecode = bytecode_addref(bytecode);
|
||||||
|
frame->ip = function->instr_off;
|
||||||
|
frame->stack_base = ctx->stack_top;
|
||||||
if(this_obj)
|
if(this_obj)
|
||||||
frame->this_obj = this_obj;
|
frame->this_obj = this_obj;
|
||||||
else if(ctx->host_global)
|
else if(ctx->host_global)
|
||||||
|
|
|
@ -178,6 +178,7 @@ typedef struct _scope_chain_t {
|
||||||
LONG ref;
|
LONG ref;
|
||||||
jsdisp_t *jsobj;
|
jsdisp_t *jsobj;
|
||||||
IDispatch *obj;
|
IDispatch *obj;
|
||||||
|
struct _call_frame_t *frame;
|
||||||
struct _scope_chain_t *next;
|
struct _scope_chain_t *next;
|
||||||
} scope_chain_t;
|
} scope_chain_t;
|
||||||
|
|
||||||
|
@ -208,17 +209,23 @@ typedef struct _call_frame_t {
|
||||||
jsdisp_t *arguments_obj;
|
jsdisp_t *arguments_obj;
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
|
|
||||||
|
unsigned pop_locals;
|
||||||
|
unsigned arguments_off;
|
||||||
|
|
||||||
bytecode_t *bytecode;
|
bytecode_t *bytecode;
|
||||||
function_code_t *function;
|
function_code_t *function;
|
||||||
|
|
||||||
struct _call_frame_t *prev_frame;
|
struct _call_frame_t *prev_frame;
|
||||||
} call_frame_t;
|
} call_frame_t;
|
||||||
|
|
||||||
|
HRESULT detach_variable_object(script_ctx_t*,call_frame_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#define EXEC_GLOBAL 0x0001
|
#define EXEC_GLOBAL 0x0001
|
||||||
#define EXEC_CONSTRUCTOR 0x0002
|
#define EXEC_CONSTRUCTOR 0x0002
|
||||||
#define EXEC_RETURN_TO_INTERP 0x0004
|
#define EXEC_RETURN_TO_INTERP 0x0004
|
||||||
|
#define EXEC_EVAL 0x0008
|
||||||
|
|
||||||
HRESULT exec_source(script_ctx_t*,DWORD,bytecode_t*,function_code_t*,scope_chain_t*,IDispatch*,
|
HRESULT exec_source(script_ctx_t*,DWORD,bytecode_t*,function_code_t*,scope_chain_t*,IDispatch*,
|
||||||
jsdisp_t*,jsdisp_t*,jsdisp_t*,jsval_t*) DECLSPEC_HIDDEN;
|
jsdisp_t*,jsdisp_t*,unsigned,jsval_t*,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;
|
HRESULT create_source_function(script_ctx_t*,bytecode_t*,function_code_t*,scope_chain_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -39,7 +39,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
jsdisp_t jsdisp;
|
jsdisp_t jsdisp;
|
||||||
FunctionInstance *function;
|
FunctionInstance *function;
|
||||||
jsdisp_t *var_obj;
|
scope_chain_t *scope;
|
||||||
} ArgumentsInstance;
|
} ArgumentsInstance;
|
||||||
|
|
||||||
static inline FunctionInstance *function_from_jsdisp(jsdisp_t *jsdisp)
|
static inline FunctionInstance *function_from_jsdisp(jsdisp_t *jsdisp)
|
||||||
|
@ -65,21 +65,6 @@ static const WCHAR applyW[] = {'a','p','p','l','y',0};
|
||||||
static const WCHAR callW[] = {'c','a','l','l',0};
|
static const WCHAR callW[] = {'c','a','l','l',0};
|
||||||
static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',0};
|
static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',0};
|
||||||
|
|
||||||
static HRESULT init_parameters(jsdisp_t *var_disp, FunctionInstance *function, unsigned argc, jsval_t *argv)
|
|
||||||
{
|
|
||||||
DWORD i=0;
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
for(i=0; i < function->func_code->param_cnt; i++) {
|
|
||||||
hres = jsdisp_propput_name(var_disp, function->func_code->params[i],
|
|
||||||
i < argc ? argv[i] : jsval_undefined());
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT Arguments_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT Arguments_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
|
@ -91,8 +76,10 @@ static void Arguments_destructor(jsdisp_t *jsdisp)
|
||||||
{
|
{
|
||||||
ArgumentsInstance *arguments = (ArgumentsInstance*)jsdisp;
|
ArgumentsInstance *arguments = (ArgumentsInstance*)jsdisp;
|
||||||
|
|
||||||
|
TRACE("(%p)\n", arguments);
|
||||||
|
|
||||||
jsdisp_release(&arguments->function->dispex);
|
jsdisp_release(&arguments->function->dispex);
|
||||||
jsdisp_release(arguments->var_obj);
|
scope_release(arguments->scope);
|
||||||
heap_free(arguments);
|
heap_free(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +95,15 @@ static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *res)
|
||||||
|
|
||||||
TRACE("%p[%u]\n", arguments, idx);
|
TRACE("%p[%u]\n", arguments, idx);
|
||||||
|
|
||||||
|
if(arguments->scope->frame) {
|
||||||
|
HRESULT hres;
|
||||||
|
hres = detach_variable_object(jsdisp->ctx, arguments->scope->frame);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Accessing by name won't work for duplicated argument names */
|
/* FIXME: Accessing by name won't work for duplicated argument names */
|
||||||
return jsdisp_propget_name(arguments->var_obj, arguments->function->func_code->params[idx], res);
|
return jsdisp_propget_name(arguments->scope->jsobj, arguments->function->func_code->params[idx], res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val)
|
static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val)
|
||||||
|
@ -118,8 +112,15 @@ static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val)
|
||||||
|
|
||||||
TRACE("%p[%u] = %s\n", arguments, idx, debugstr_jsval(val));
|
TRACE("%p[%u] = %s\n", arguments, idx, debugstr_jsval(val));
|
||||||
|
|
||||||
|
if(arguments->scope->frame) {
|
||||||
|
HRESULT hres;
|
||||||
|
hres = detach_variable_object(jsdisp->ctx, arguments->scope->frame);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Accessing by name won't work for duplicated argument names */
|
/* FIXME: Accessing by name won't work for duplicated argument names */
|
||||||
return jsdisp_propput_name(arguments->var_obj, arguments->function->func_code->params[idx], val);
|
return jsdisp_propput_name(arguments->scope->jsobj, arguments->function->func_code->params[idx], val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const builtin_info_t Arguments_info = {
|
static const builtin_info_t Arguments_info = {
|
||||||
|
@ -133,7 +134,7 @@ static const builtin_info_t Arguments_info = {
|
||||||
Arguments_idx_put
|
Arguments_idx_put
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT create_arguments(script_ctx_t *ctx, FunctionInstance *calee, jsdisp_t *var_obj,
|
static HRESULT create_arguments(script_ctx_t *ctx, FunctionInstance *calee, scope_chain_t *scope,
|
||||||
unsigned argc, jsval_t *argv, jsdisp_t **ret)
|
unsigned argc, jsval_t *argv, jsdisp_t **ret)
|
||||||
{
|
{
|
||||||
ArgumentsInstance *args;
|
ArgumentsInstance *args;
|
||||||
|
@ -154,7 +155,7 @@ static HRESULT create_arguments(script_ctx_t *ctx, FunctionInstance *calee, jsdi
|
||||||
|
|
||||||
jsdisp_addref(&calee->dispex);
|
jsdisp_addref(&calee->dispex);
|
||||||
args->function = calee;
|
args->function = calee;
|
||||||
args->var_obj = jsdisp_addref(var_obj);
|
args->scope = scope_addref(scope);
|
||||||
|
|
||||||
/* Store unnamed arguments directly in arguments object */
|
/* Store unnamed arguments directly in arguments object */
|
||||||
for(i = calee->length; i < argc; i++) {
|
for(i = calee->length; i < argc; i++) {
|
||||||
|
@ -182,25 +183,6 @@ static HRESULT create_arguments(script_ctx_t *ctx, FunctionInstance *calee, jsdi
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT create_var_disp(script_ctx_t *ctx, FunctionInstance *function, unsigned argc, jsval_t *argv, jsdisp_t **ret)
|
|
||||||
{
|
|
||||||
jsdisp_t *var_disp;
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = create_dispex(ctx, NULL, NULL, &var_disp);
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
|
|
||||||
hres = init_parameters(var_disp, function, argc, argv);
|
|
||||||
if(FAILED(hres)) {
|
|
||||||
jsdisp_release(var_disp);
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = var_disp;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv,
|
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)
|
BOOL is_constructor, BOOL caller_execs_source, jsval_t *r)
|
||||||
{
|
{
|
||||||
|
@ -218,24 +200,22 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = create_var_disp(ctx, function, argc, argv, &var_disp);
|
hres = create_dispex(ctx, NULL, NULL, &var_disp);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = create_arguments(ctx, function, var_disp, argc, argv, &arg_disp);
|
|
||||||
if(FAILED(hres)) {
|
|
||||||
jsdisp_release(var_disp);
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
hres = jsdisp_propput(var_disp, argumentsW, PROPF_DONTDELETE, jsval_obj(arg_disp));
|
|
||||||
if(FAILED(hres)) {
|
|
||||||
jsdisp_release(arg_disp);
|
|
||||||
jsdisp_release(var_disp);
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
|
hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
|
||||||
|
jsdisp_release(var_disp);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
hres = create_arguments(ctx, function, scope, argc, argv, &arg_disp);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
scope_release(scope);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = jsdisp_propput(scope->jsobj, argumentsW, PROPF_DONTDELETE, jsval_obj(arg_disp));
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
DWORD exec_flags = 0;
|
DWORD exec_flags = 0;
|
||||||
|
|
||||||
|
@ -244,13 +224,12 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
|
||||||
if(is_constructor)
|
if(is_constructor)
|
||||||
exec_flags |= EXEC_CONSTRUCTOR;
|
exec_flags |= EXEC_CONSTRUCTOR;
|
||||||
hres = exec_source(ctx, exec_flags, function->code, function->func_code, scope, this_obj,
|
hres = exec_source(ctx, exec_flags, function->code, function->func_code, scope, this_obj,
|
||||||
&function->dispex, var_disp, arg_disp, r);
|
&function->dispex, scope->jsobj, argc, argv, arg_disp, r);
|
||||||
|
|
||||||
scope_release(scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsdisp_release(arg_disp);
|
jsdisp_release(arg_disp);
|
||||||
jsdisp_release(var_disp);
|
scope_release(scope);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
call_frame_t *frame;
|
call_frame_t *frame;
|
||||||
DWORD exec_flags = 0;
|
DWORD exec_flags = EXEC_EVAL;
|
||||||
bytecode_t *code;
|
bytecode_t *code;
|
||||||
const WCHAR *src;
|
const WCHAR *src;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -229,7 +229,7 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
|
||||||
if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE)
|
if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE)
|
||||||
exec_flags |= EXEC_RETURN_TO_INTERP;
|
exec_flags |= EXEC_RETURN_TO_INTERP;
|
||||||
hres = exec_source(ctx, exec_flags, code, &code->global_code, frame->scope,
|
hres = exec_source(ctx, exec_flags, code, &code->global_code, frame->scope,
|
||||||
frame->this_obj, NULL, frame->variable_obj, NULL, r);
|
frame->this_obj, NULL, frame->variable_obj, 0, NULL, NULL, r);
|
||||||
release_bytecode(code);
|
release_bytecode(code);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ static HRESULT exec_global_code(JScript *This, bytecode_t *code)
|
||||||
IActiveScriptSite_OnEnterScript(This->site);
|
IActiveScriptSite_OnEnterScript(This->site);
|
||||||
|
|
||||||
clear_ei(This->ctx);
|
clear_ei(This->ctx);
|
||||||
hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, NULL, NULL);
|
hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL, NULL);
|
||||||
|
|
||||||
IActiveScriptSite_OnLeaveScript(This->site);
|
IActiveScriptSite_OnLeaveScript(This->site);
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -773,7 +773,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
|
||||||
IActiveScriptSite_OnEnterScript(This->site);
|
IActiveScriptSite_OnEnterScript(This->site);
|
||||||
|
|
||||||
clear_ei(This->ctx);
|
clear_ei(This->ctx);
|
||||||
hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, NULL, &r);
|
hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL, &r);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
if(pvarResult)
|
if(pvarResult)
|
||||||
hres = jsval_to_variant(r, pvarResult);
|
hres = jsval_to_variant(r, pvarResult);
|
||||||
|
|
Loading…
Reference in New Issue