Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 39 +++++++++++++++++++++++++++++---------- dlls/jscript/engine.h | 2 +- dlls/jscript/function.c | 6 ++---- dlls/jscript/global.c | 2 +- dlls/jscript/jscript.c | 6 +++--- 5 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 5a627ea..a78a42b 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2984,8 +2984,9 @@ static HRESULT setup_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t }
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, unsigned argc, jsval_t *argv, jsval_t *r) + IDispatch *this_obj, jsdisp_t *function_instance, unsigned argc, jsval_t *argv, jsval_t *r) { + jsdisp_t *variable_obj; call_frame_t *frame; unsigned i; HRESULT hres; @@ -2997,6 +2998,18 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi } }
+ if(flags & (EXEC_GLOBAL | EXEC_EVAL)) { + if(ctx->call_ctx) + variable_obj = ctx->call_ctx->variable_obj; + else + variable_obj = ctx->global; + jsdisp_addref(variable_obj); + } + else { + hres = create_dispex(ctx, NULL, NULL, &variable_obj); + if(FAILED(hres)) return hres; + } + if(!ctx->ei->enter_notified) { ctx->ei->enter_notified = TRUE; IActiveScriptSite_OnEnterScript(ctx->site); @@ -3010,12 +3023,12 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
hres = create_source_function(ctx, bytecode, function->funcs+i, scope, &func_obj); if(FAILED(hres)) - return hres; + goto fail;
hres = bind_event_target(ctx, function->funcs+i, func_obj); jsdisp_release(func_obj); if(FAILED(hres)) - return hres; + goto fail; }
if(flags & (EXEC_GLOBAL | EXEC_EVAL)) { @@ -3028,7 +3041,7 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
hres = create_source_function(ctx, bytecode, function->funcs+function->variables[i].func_id, scope, &func_obj); if(FAILED(hres)) - return hres; + goto fail;
hres = jsdisp_propput_name(variable_obj, function->variables[i].name, jsval_obj(func_obj)); jsdisp_release(func_obj); @@ -3037,7 +3050,7 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
hres = jsdisp_get_id(variable_obj, function->variables[i].name, fdexNameEnsure, &id); if(FAILED(hres)) - return hres; + goto fail; } } } @@ -3057,12 +3070,14 @@ 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, FALSE); if(FAILED(hres)) - return hres; + goto fail; }
frame = heap_alloc_zero(sizeof(*frame)); - if(!frame) - return E_OUTOFMEMORY; + if(!frame) { + hres = E_OUTOFMEMORY; + goto fail; + }
frame->function = function; frame->ret = jsval_undefined(); @@ -3074,7 +3089,7 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi if(FAILED(hres)) { release_bytecode(frame->bytecode); heap_free(frame); - return hres; + goto fail; } }else if(scope) { frame->base_scope = frame->scope = scope_addref(scope); @@ -3091,7 +3106,7 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi frame->function_instance = jsdisp_addref(function_instance);
frame->flags = flags; - frame->variable_obj = jsdisp_addref(variable_obj); + frame->variable_obj = variable_obj;
frame->prev_frame = ctx->call_ctx; ctx->call_ctx = frame; @@ -3107,4 +3122,8 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi }
return enter_bytecode(ctx, r); + +fail: + jsdisp_release(variable_obj); + return hres; } diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index fe6b2a0..2a8e405 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -281,7 +281,7 @@ typedef struct _call_frame_t { #define EXEC_EVAL 0x0008
HRESULT exec_source(script_ctx_t*,DWORD,bytecode_t*,function_code_t*,scope_chain_t*,IDispatch*, - jsdisp_t*,jsdisp_t*,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; + jsdisp_t*,unsigned,jsval_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 setup_arguments_object(script_ctx_t*,call_frame_t*) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 007aec0..e1a8c29 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -722,7 +722,7 @@ static HRESULT InterpretedFunction_call(script_ctx_t *ctx, FunctionInstance *fun unsigned argc, jsval_t *argv, jsval_t *r) { InterpretedFunction *function = (InterpretedFunction*)func; - jsdisp_t *var_disp, *new_obj = NULL; + jsdisp_t *new_obj = NULL; DWORD exec_flags = 0; HRESULT hres;
@@ -745,14 +745,12 @@ static HRESULT InterpretedFunction_call(script_ctx_t *ctx, FunctionInstance *fun 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->function.dispex, var_disp, argc, argv, r); + &function->function.dispex, argc, argv, r); if(new_obj) jsdisp_release(new_obj);
- jsdisp_release(var_disp); return hres; }
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index 2a1dcb2..64b910f 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -215,7 +215,7 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) exec_flags |= EXEC_RETURN_TO_INTERP; hres = exec_source(ctx, exec_flags, code, &code->global_code, frame ? frame->scope : NULL, - frame ? frame->this_obj : NULL, NULL, frame ? frame->variable_obj : ctx->global, 0, NULL, r); + frame ? frame->this_obj : NULL, NULL, 0, NULL, r); release_bytecode(code); return hres; } diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index aabad7e..f54c34a 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -408,7 +408,7 @@ static void exec_queued_code(JScript *This)
LIST_FOR_EACH_ENTRY(iter, &This->queued_code, bytecode_t, entry) { enter_script(This->ctx, &ei); - hres = exec_source(This->ctx, EXEC_GLOBAL, iter, &iter->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL); + hres = exec_source(This->ctx, EXEC_GLOBAL, iter, &iter->global_code, NULL, NULL, NULL, 0, NULL, NULL); leave_script(This->ctx, hres); if(FAILED(hres)) break; @@ -1053,7 +1053,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, if(dwFlags & SCRIPTTEXT_ISEXPRESSION) { jsval_t r;
- hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, &r); + hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, 0, NULL, &r); if(SUCCEEDED(hres)) { if(pvarResult) hres = jsval_to_variant(r, pvarResult); @@ -1072,7 +1072,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, if(!pvarResult && !is_started(This->ctx)) { list_add_tail(&This->queued_code, &code->entry); }else { - hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, This->ctx->global, 0, NULL, NULL); + hres = exec_source(This->ctx, EXEC_GLOBAL, code, &code->global_code, NULL, NULL, NULL, 0, NULL, NULL); if(code->is_persistent) list_add_tail(&This->persistent_code, &code->entry); else
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index a78a42b..2e64a1c 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -3001,6 +3001,8 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi if(flags & (EXEC_GLOBAL | EXEC_EVAL)) { if(ctx->call_ctx) variable_obj = ctx->call_ctx->variable_obj; + else if(bytecode->named_item) + variable_obj = bytecode->named_item->script_obj; else variable_obj = ctx->global; jsdisp_addref(variable_obj);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 2e64a1c..fed1bf3 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -669,6 +669,15 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re return S_OK; } } + + if(ctx->call_ctx->bytecode->named_item) { + jsdisp_t *script_obj = ctx->call_ctx->bytecode->named_item->script_obj; + hres = jsdisp_get_id(script_obj, identifier, 0, &id); + if(SUCCEEDED(hres)) { + exprval_set_disp_ref(ret, to_disp(script_obj), id); + return S_OK; + } + } }
hres = jsdisp_get_id(ctx->global, identifier, 0, &id); @@ -1254,13 +1263,17 @@ static HRESULT interp_identifier_ref(script_ctx_t *ctx, BSTR identifier, unsigne return hres;
if(exprval.type == EXPRVAL_INVALID && (flags & fdexNameEnsure)) { + jsdisp_t *script_obj = ctx->global; DISPID id;
- hres = jsdisp_get_id(ctx->global, identifier, fdexNameEnsure, &id); + if(ctx->call_ctx->bytecode->named_item) + script_obj = ctx->call_ctx->bytecode->named_item->script_obj; + + hres = jsdisp_get_id(script_obj, identifier, fdexNameEnsure, &id); if(FAILED(hres)) return hres;
- exprval_set_disp_ref(&exprval, to_disp(ctx->global), id); + exprval_set_disp_ref(&exprval, to_disp(script_obj), id); }
if(exprval.type == EXPRVAL_JSVAL || exprval.type == EXPRVAL_INVALID) {
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/jscript.c | 13 +++++++++---- dlls/jscript/tests/jscript.c | 18 ------------------ 2 files changed, 9 insertions(+), 22 deletions(-)
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index f54c34a..31277c6 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -110,10 +110,15 @@ static inline BOOL is_started(script_ctx_t *ctx)
HRESULT create_named_item_script_obj(script_ctx_t *ctx, named_item_t *item) { - /* FIXME: Create a separate script dispatch instead of using the global */ - item->script_obj = ctx->global; - IDispatchEx_AddRef(&item->script_obj->IDispatchEx_iface); - return S_OK; + static const builtin_info_t disp_info = { + JSCLASS_GLOBAL, + {NULL, NULL, 0}, + 0, NULL, + NULL, + NULL + }; + + return create_dispex(ctx, &disp_info, NULL, &item->script_obj); }
static void release_named_item_script_obj(named_item_t *item) diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index ed56f8c..61e24fe 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -1203,7 +1203,6 @@ static void test_named_items(void) ok(dispex == dispex2, "get_script_dispatch returned different dispatch objects.\n"); IDispatchEx_Release(dispex2); dispex2 = get_script_dispatch(script, L"codeOnlyItem"); - todo_wine ok(dispex != dispex2, "get_script_dispatch returned same dispatch objects.\n");
SET_EXPECT(OnStateChange_INITIALIZED); @@ -1334,9 +1333,7 @@ static void test_named_items(void)
id = 0; hr = IDispatchEx_GetDispID(dispex2, bstr, 0, &id); - todo_wine ok(hr == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(global_idents[i]), hr); - todo_wine ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(global_idents[i]), id); SysFreeString(bstr); } @@ -1346,9 +1343,7 @@ static void test_named_items(void) bstr = SysAllocString(context_idents[i]); id = 0; hr = IDispatchEx_GetDispID(dispex, bstr, 0, &id); - todo_wine ok(hr == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr); - todo_wine ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(context_idents[i]), id); id = 0; hr = IDispatchEx_GetDispID(dispex2, bstr, 0, &id); @@ -1382,12 +1377,9 @@ static void test_named_items(void) SET_EXPECT(OnScriptError); SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL); - todo_wine ok(FAILED(hr), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hr); CHECK_CALLED(OnEnterScript); - todo_wine_if(i != 0) CHECK_CALLED(GetIDsOfNames); - todo_wine CHECK_CALLED(OnScriptError); CHECK_CALLED(OnLeaveScript);
@@ -1499,9 +1491,7 @@ static void test_named_items(void) bstr = SysAllocString(context_idents[i]); id = 0; hr = IDispatchEx_GetDispID(dispex, bstr, 0, &id); - todo_wine_if(i != 0) ok(hr == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr); - todo_wine_if(i != 0) ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(context_idents[i]), id); SysFreeString(bstr); } @@ -1540,9 +1530,7 @@ static void test_named_items(void) bstr = SysAllocString(global_idents[i]); id = 0; hr = IDispatchEx_GetDispID(dispex, bstr, 0, &id); - todo_wine ok(hr == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(global_idents[i]), hr); - todo_wine ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(global_idents[i]), id); SysFreeString(bstr); } @@ -1552,9 +1540,7 @@ static void test_named_items(void) bstr = SysAllocString(context_idents[i]); id = 0; hr = IDispatchEx_GetDispID(dispex, bstr, 0, &id); - todo_wine_if(i != 0) ok(hr == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr); - todo_wine_if(i != 0) ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(context_idents[i]), id); SysFreeString(bstr); } @@ -1582,10 +1568,8 @@ static void test_named_items(void) SET_EXPECT(OnScriptError); SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL); - todo_wine_if(i != 0) ok(FAILED(hr), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hr); CHECK_CALLED(OnEnterScript); - todo_wine_if(i != 0) CHECK_CALLED(OnScriptError); CHECK_CALLED(OnLeaveScript);
@@ -1593,10 +1577,8 @@ static void test_named_items(void) SET_EXPECT(OnScriptError); SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], L"codeOnlyItem", NULL, NULL, 0, 0, 0, NULL, NULL); - todo_wine_if(i != 0) ok(FAILED(hr), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hr); CHECK_CALLED(OnEnterScript); - todo_wine_if(i != 0) CHECK_CALLED(OnScriptError); CHECK_CALLED(OnLeaveScript); }
Hi Gabriel,
On 12.03.2020 17:35, Gabriel Ivăncescu wrote:
@@ -2997,6 +2998,18 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi } }
- if(flags & (EXEC_GLOBAL | EXEC_EVAL)) {
if(ctx->call_ctx)
variable_obj = ctx->call_ctx->variable_obj;
I think that only eval() should inherit caller's variable_obj. It would be even better to do that only for eval with EXEC_RETURN_TO_INTERP.
Thanks,
Jacek
On 12/03/2020 18:55, Jacek Caban wrote:
Hi Gabriel,
On 12.03.2020 17:35, Gabriel Ivăncescu wrote:
@@ -2997,6 +2998,18 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi } } + if(flags & (EXEC_GLOBAL | EXEC_EVAL)) { + if(ctx->call_ctx) + variable_obj = ctx->call_ctx->variable_obj;
I think that only eval() should inherit caller's variable_obj. It would be even better to do that only for eval with EXEC_RETURN_TO_INTERP.
Thanks,
Jacek
If I include EXEC_RETURN_TO_INTERP, it has test failures in run.c, I'll send one with just EXEC_EVAL instead.