static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *var_disp, *arg_disp; exec_ctx_t *exec_ctx; scope_chain_t *scope; 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_var_disp(ctx, function, argc, argv, &var_disp); if(FAILED(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); if(SUCCEEDED(hres)) { hres = create_exec_ctx(ctx, this_obj, var_disp, scope, FALSE, &exec_ctx); scope_release(scope); if(SUCCEEDED(hres)) { jsdisp_t *prev_args; prev_args = function->arguments; function->arguments = arg_disp; hres = exec_source(exec_ctx, function->code, function->func_code, FALSE, r); function->arguments = prev_args; exec_release(exec_ctx); } } /* 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 */ jsdisp_propput_name(var_disp, argumentsW, jsval_undefined()); jsdisp_release(arg_disp); jsdisp_release(var_disp); return hres; }
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, *arg_disp; scope_chain_t *scope; 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_var_disp(ctx, function, argc, argv, &var_disp); if(FAILED(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); if(SUCCEEDED(hres)) { DWORD exec_flags = 0; 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, scope, this_obj, &function->dispex, var_disp, arg_disp, r); scope_release(scope); } jsdisp_release(arg_disp); jsdisp_release(var_disp); return hres; }