Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 7da8f70..3946d02 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -1218,12 +1218,15 @@ static HRESULT interp_call_member(script_ctx_t *ctx) /* ECMA-262 3rd Edition 11.1.1 */ static HRESULT interp_this(script_ctx_t *ctx) { - call_frame_t *frame = ctx->call_ctx; + IDispatch *this_obj = ctx->call_ctx->this_obj;
TRACE("\n");
- IDispatch_AddRef(frame->this_obj); - return stack_push(ctx, jsval_disp(frame->this_obj)); + if(!this_obj) + this_obj = ctx->host_global ? ctx->host_global : to_disp(ctx->global); + + IDispatch_AddRef(this_obj); + return stack_push(ctx, jsval_disp(this_obj)); }
static HRESULT interp_identifier_ref(script_ctx_t *ctx, BSTR identifier, unsigned flags) @@ -2700,7 +2703,7 @@ static void print_backtrace(script_ctx_t *ctx) WARN("%u\t", depth); depth++;
- if(frame->this_obj && frame->this_obj != to_disp(ctx->global) && frame->this_obj != ctx->host_global) + if(frame->this_obj) WARN("%p->", frame->this_obj); WARN("%s(", frame->function->name ? debugstr_w(frame->function->name) : "[unnamed]"); if(frame->base_scope && frame->base_scope->frame) { @@ -3055,13 +3058,10 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
frame->ip = function->instr_off; frame->stack_base = ctx->stack_top; - if(this_obj) + if(this_obj) { frame->this_obj = this_obj; - else if(ctx->host_global) - frame->this_obj = ctx->host_global; - else - frame->this_obj = to_disp(ctx->global); - IDispatch_AddRef(frame->this_obj); + IDispatch_AddRef(frame->this_obj); + }
if(function_instance) frame->function_instance = jsdisp_addref(function_instance);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 17 ++++++++++++++++- dlls/jscript/engine.h | 1 + dlls/jscript/function.c | 4 +--- dlls/jscript/jscript.c | 10 ---------- dlls/jscript/jscript.h | 2 -- dlls/jscript/tests/jscript.c | 2 -- 6 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 3946d02..ce7fbbc 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -605,6 +605,21 @@ static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t return FALSE; }
+IDispatch *lookup_global_host(script_ctx_t *ctx) +{ + IDispatch *disp = NULL; + named_item_t *item; + + LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) { + if(!(item->flags & SCRIPTITEM_GLOBALMEMBERS)) continue; + disp = item->disp; + break; + } + if(!disp) disp = to_disp(ctx->global); + + return disp; +} + static int __cdecl local_ref_cmp(const void *key, const void *ref) { return wcscmp((const WCHAR*)key, ((const local_ref_t*)ref)->name); @@ -1223,7 +1238,7 @@ static HRESULT interp_this(script_ctx_t *ctx) TRACE("\n");
if(!this_obj) - this_obj = ctx->host_global ? ctx->host_global : to_disp(ctx->global); + this_obj = lookup_global_host(ctx);
IDispatch_AddRef(this_obj); return stack_push(ctx, jsval_disp(this_obj)); diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index cad46e1..7be98c5 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -170,6 +170,7 @@ typedef struct _function_code_t { bytecode_t *bytecode; } function_code_t;
+IDispatch *lookup_global_host(script_ctx_t*) DECLSPEC_HIDDEN; local_ref_t *lookup_local(const function_code_t*,const WCHAR*) DECLSPEC_HIDDEN;
struct _bytecode_t { diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index baa5eb1..ef0de96 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -612,10 +612,8 @@ static HRESULT NativeFunction_call(script_ctx_t *ctx, FunctionInstance *func, ID
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); + set_disp(&vthis, lookup_global_host(ctx));
hres = function->proc(ctx, &vthis, flags & ~DISPATCH_JSCRIPT_INTERNAL_MASK, argc, argv, r);
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index b878aa5..36d9f84 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -409,11 +409,6 @@ static void decrease_state(JScript *This, SCRIPTSTATE state) case SCRIPTSTATE_INITIALIZED: clear_script_queue(This);
- if(This->ctx->host_global) { - IDispatch_Release(This->ctx->host_global); - This->ctx->host_global = NULL; - } - while(!list_empty(&This->ctx->named_items)) { named_item_t *iter = LIST_ENTRY(list_head(&This->ctx->named_items), named_item_t, entry);
@@ -820,11 +815,6 @@ static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface, WARN("object does not implement IDispatch\n"); return hres; } - - if(This->ctx->host_global) - IDispatch_Release(This->ctx->host_global); - IDispatch_AddRef(disp); - This->ctx->host_global = disp; }
item = heap_alloc(sizeof(*item)); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 7f34b55..f9d6992 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -422,8 +422,6 @@ struct _script_ctx_t {
heap_pool_t tmp_heap;
- IDispatch *host_global; - jsval_t *stack; unsigned stack_size; unsigned stack_top; diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index a7dfd11..8d4f6e1 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -1394,7 +1394,6 @@ static void test_named_items(void) SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, L"this", NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); - todo_wine ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == &global_named_item, "Unexpected 'this': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var)); VariantClear(&var); @@ -1427,7 +1426,6 @@ static void test_named_items(void) SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, L"globalCode_this", NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); - todo_wine ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == &global_named_item, "Unexpected 'this': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var)); VariantClear(&var);
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/compile.c | 2 ++ dlls/jscript/engine.h | 1 + dlls/jscript/global.c | 5 +++++ dlls/jscript/jscript.c | 29 ++++++++++++++++++++++++++++- 4 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 61db10c..07027c2 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -2250,6 +2250,8 @@ void release_bytecode(bytecode_t *code) for(i=0; i < code->str_cnt; i++) jsstr_release(code->str_pool[i]);
+ if(code->named_item) + release_named_item(code->named_item); heap_free(code->source); heap_pool_free(&code->heap); heap_free(code->bstr_pool); diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 7be98c5..dcd153c 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -181,6 +181,7 @@ struct _bytecode_t { heap_pool_t heap;
function_code_t global_code; + named_item_t *named_item;
WCHAR *source; UINT64 source_context; diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index e2758bf..8f593a9 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -210,6 +210,11 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a return hres; }
+ if(frame && frame->bytecode->named_item) { + code->named_item = frame->bytecode->named_item; + code->named_item->ref++; + } + if(!frame || (frame->flags & EXEC_GLOBAL)) exec_flags |= EXEC_GLOBAL; if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 36d9f84..8976e6b 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -983,6 +983,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { JScript *This = impl_from_IActiveScriptParse(iface); + named_item_t *item = NULL; bytecode_t *code; jsexcept_t ei; HRESULT hres; @@ -994,11 +995,23 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED;
+ if(pstrItemName) { + item = lookup_named_item(This->ctx, pstrItemName, 0); + if(!item) { + WARN("Unknown context %s\n", debugstr_w(pstrItemName)); + return E_INVALIDARG; + } + } + enter_script(This->ctx, &ei); hres = compile_script(This->ctx, pstrCode, dwSourceContextCookie, ulStartingLine, NULL, pstrDelimiter, (dwFlags & SCRIPTTEXT_ISEXPRESSION) != 0, This->is_encode, &code); if(FAILED(hres)) return leave_script(This->ctx, hres); + if(item) { + code->named_item = item; + item->ref++; + }
if(dwFlags & SCRIPTTEXT_ISEXPRESSION) { jsval_t r; @@ -1075,6 +1088,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp) { JScript *This = impl_from_IActiveScriptParseProcedure2(iface); + named_item_t *item = NULL; bytecode_t *code; jsdisp_t *dispex; jsexcept_t ei; @@ -1087,11 +1101,24 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED;
+ if(pstrItemName) { + item = lookup_named_item(This->ctx, pstrItemName, 0); + if(!item) { + WARN("Unknown context %s\n", debugstr_w(pstrItemName)); + return E_INVALIDARG; + } + } + enter_script(This->ctx, &ei); hres = compile_script(This->ctx, pstrCode, dwSourceContextCookie, ulStartingLineNumber, pstrFormalParams, pstrDelimiter, FALSE, This->is_encode, &code); - if(SUCCEEDED(hres)) + if(SUCCEEDED(hres)) { + if(item) { + code->named_item = item; + item->ref++; + } hres = create_source_function(This->ctx, code, &code->global_code, NULL, &dispex); + } release_bytecode(code); hres = leave_script(This->ctx, hres); if(FAILED(hres))
Hi Gabriel,
You could add named item as compile_script argument instead of modifying result of each compile_script call. Also, what about functions created by function constructor in function.c?
Thanks, Jacek
On 06/03/2020 16:40, Jacek Caban wrote:
Hi Gabriel,
You could add named item as compile_script argument instead of modifying result of each compile_script call. Also, what about functions created by function constructor in function.c?
Thanks, Jacek
Right. I will still have to pass the item, though (i.e. after looking it up), due to the compile_script in eval, and look it up in the respective two functions.
For the function constructor in function.c, there's no named item, so I guess I'll just pass NULL. That's because it's only for native functions, if I understand correctly. And those are only in the global object.
If my assumption is wrong, any idea how to retrieve the named item there?
Thanks, Gabriel
On 06.03.2020 16:19, Gabriel Ivăncescu wrote:
On 06/03/2020 16:40, Jacek Caban wrote:
Hi Gabriel,
You could add named item as compile_script argument instead of modifying result of each compile_script call. Also, what about functions created by function constructor in function.c?
Thanks, Jacek
Right. I will still have to pass the item, though (i.e. after looking it up), due to the compile_script in eval, and look it up in the respective two functions.
For the function constructor in function.c, there's no named item, so I guess I'll just pass NULL. That's because it's only for native functions, if I understand correctly. And those are only in the global object.
If my assumption is wrong, any idea how to retrieve the named item there?
No, an of it in JavaScript code is:
func = new Function("return 3;");
There are more examples in api.js.
Jacek
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 7 +++++++ dlls/jscript/jscript.c | 39 +++++++++++++++++++++++++++++++++++++++ dlls/jscript/jscript.h | 2 ++ 3 files changed, 48 insertions(+)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index ce7fbbc..5b96895 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2990,6 +2990,13 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi unsigned i; HRESULT hres;
+ if(bytecode->named_item) { + if(!bytecode->named_item->script_obj) { + hres = create_named_item_script_obj(ctx, bytecode->named_item); + if(FAILED(hres)) return hres; + } + } + if(!ctx->ei->enter_notified) { ctx->ei->enter_notified = TRUE; IActiveScriptSite_OnEnterScript(ctx->site); diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 8976e6b..b74f172 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -108,6 +108,27 @@ static inline BOOL is_started(script_ctx_t *ctx) || ctx->state == SCRIPTSTATE_DISCONNECTED; }
+HRESULT create_named_item_script_obj(script_ctx_t *ctx, named_item_t *item) +{ + 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) +{ + if(!item->script_obj) return; + + jsdisp_release(item->script_obj); + item->script_obj = NULL; +} + named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *item_name, unsigned flags) { named_item_t *item; @@ -115,6 +136,10 @@ named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *item_name, unsig
LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) { if((item->flags & flags) == flags && !wcscmp(item->name, item_name)) { + if(!item->script_obj && !(item->flags & SCRIPTITEM_GLOBALMEMBERS)) { + hr = create_named_item_script_obj(ctx, item); + if(FAILED(hr)) return NULL; + } if(!item->disp && (flags || !(item->flags & SCRIPTITEM_CODEONLY))) { IUnknown *unk;
@@ -371,6 +396,15 @@ static void clear_persistent_code_list(JScript *This) } }
+static void release_persistent_script_objs(JScript *This) +{ + bytecode_t *iter; + + LIST_FOR_EACH_ENTRY(iter, &This->persistent_code, bytecode_t, entry) + if(iter->named_item) + release_named_item_script_obj(iter->named_item); +} + static void exec_queued_code(JScript *This) { bytecode_t *iter; @@ -408,6 +442,7 @@ static void decrease_state(JScript *This, SCRIPTSTATE state) /* FALLTHROUGH */ case SCRIPTSTATE_INITIALIZED: clear_script_queue(This); + release_persistent_script_objs(This);
while(!list_empty(&This->ctx->named_items)) { named_item_t *iter = LIST_ENTRY(list_head(&This->ctx->named_items), named_item_t, entry); @@ -415,6 +450,7 @@ static void decrease_state(JScript *This, SCRIPTSTATE state) list_remove(&iter->entry); if(iter->disp) IDispatch_Release(iter->disp); + release_named_item_script_obj(iter); release_named_item(iter); }
@@ -827,6 +863,7 @@ static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface, item->ref = 1; item->disp = disp; item->flags = dwFlags; + item->script_obj = NULL; item->name = heap_strdupW(pstrName); if(!item->name) { if(disp) @@ -1001,6 +1038,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, WARN("Unknown context %s\n", debugstr_w(pstrItemName)); return E_INVALIDARG; } + if(!item->script_obj) item = NULL; }
enter_script(This->ctx, &ei); @@ -1107,6 +1145,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars WARN("Unknown context %s\n", debugstr_w(pstrItemName)); return E_INVALIDARG; } + if(!item->script_obj) item = NULL; }
enter_script(This->ctx, &ei); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index f9d6992..804f95e 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -205,6 +205,7 @@ typedef HRESULT (*builtin_setter_t)(script_ctx_t*,jsdisp_t*,jsval_t); HRESULT builtin_set_const(script_ctx_t*,jsdisp_t*,jsval_t) DECLSPEC_HIDDEN;
typedef struct named_item_t { + jsdisp_t *script_obj; IDispatch *disp; unsigned ref; DWORD flags; @@ -213,6 +214,7 @@ typedef struct named_item_t { struct list entry; } named_item_t;
+HRESULT create_named_item_script_obj(script_ctx_t*,named_item_t*) DECLSPEC_HIDDEN; named_item_t *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN; void release_named_item(named_item_t*) DECLSPEC_HIDDEN;
Hi Gabriel,
On 06.03.2020 14:48, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
dlls/jscript/engine.c | 7 +++++++ dlls/jscript/jscript.c | 39 +++++++++++++++++++++++++++++++++++++++ dlls/jscript/jscript.h | 2 ++ 3 files changed, 48 insertions(+)
Thanks for splitting patches, it's much easier to read them now. However, I think they will have to be reordered with this patch in the end. Otherwise this patchset may break some scripts in a middle. For example, if you apply the first 5 patches, scripts will use global object, but host may try to interact with them using the new named item object. If you set it to global object initially, everything will continue to use global object, but in a new, named item aware, way. Once all users are dealt with, you may add separated object with a simple patch like this one.
Thanks,
Jacek
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/jscript.c | 10 +++++++++- dlls/jscript/tests/jscript.c | 9 ++------- 2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index b74f172..535f95d 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -888,6 +888,7 @@ static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR IDispatch **ppdisp) { JScript *This = impl_from_IActiveScript(iface); + jsdisp_t *script_obj;
TRACE("(%p)->(%s %p)\n", This, debugstr_w(pstrItemName), ppdisp);
@@ -899,7 +900,14 @@ static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR return E_UNEXPECTED; }
- *ppdisp = to_disp(This->ctx->global); + script_obj = This->ctx->global; + if(pstrItemName) { + named_item_t *item = lookup_named_item(This->ctx, pstrItemName, 0); + if(!item) return E_INVALIDARG; + if(item->script_obj) script_obj = item->script_obj; + } + + *ppdisp = to_disp(script_obj); IDispatch_AddRef(*ppdisp); return S_OK; } diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index 8d4f6e1..40a8456 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -1196,7 +1196,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); @@ -1325,9 +1324,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); } @@ -1343,7 +1340,9 @@ static void test_named_items(void) 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); + todo_wine ok(hr == S_OK, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr); + todo_wine ok(id != -1, "[%s] id = -1\n", wine_dbgstr_w(context_idents[i])); SysFreeString(bstr); } @@ -1531,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); } @@ -1543,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); }
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 1 + dlls/jscript/engine.c | 19 +++++++++++++++++-- dlls/jscript/engine.h | 1 + dlls/jscript/global.c | 4 +++- dlls/jscript/tests/jscript.c | 13 ------------- 5 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index e986de6..a0c8f38 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1527,6 +1527,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc }
enter_script(This->ctx, &ei); + ei.script_obj = This;
switch(wFlags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 5b96895..044e32c 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) { @@ -2995,6 +3008,8 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi hres = create_named_item_script_obj(ctx, bytecode->named_item); if(FAILED(hres)) return hres; } + if(variable_obj == ctx->global) + variable_obj = bytecode->named_item->script_obj; }
if(!ctx->ei->enter_notified) { diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index dcd153c..4a54ddf 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -233,6 +233,7 @@ struct _jsexcept_t { jsstr_t *message; jsstr_t *line;
+ jsdisp_t *script_obj; bytecode_t *code; unsigned loc;
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index 8f593a9..bb53709 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -181,6 +181,7 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a { call_frame_t *frame = ctx->call_ctx; DWORD exec_flags = EXEC_EVAL; + jsdisp_t *context; bytecode_t *code; const WCHAR *src; HRESULT hres; @@ -214,13 +215,14 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a code->named_item = frame->bytecode->named_item; code->named_item->ref++; } + context = frame ? frame->variable_obj : (ctx->ei->script_obj ? ctx->ei->script_obj : ctx->global);
if(!frame || (frame->flags & EXEC_GLOBAL)) exec_flags |= EXEC_GLOBAL; 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, context, 0, NULL, r); release_bytecode(code); return hres; } diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index 40a8456..f0f8c70 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -1334,15 +1334,11 @@ 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); - todo_wine ok(hr == S_OK, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(context_idents[i]), hr); - todo_wine ok(id != -1, "[%s] id = -1\n", wine_dbgstr_w(context_idents[i])); SysFreeString(bstr); } @@ -1372,12 +1368,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);
@@ -1489,9 +1482,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); } @@ -1568,10 +1559,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);
@@ -1579,10 +1568,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); }
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 5 +++++ dlls/jscript/tests/jscript.c | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 044e32c..3e32ea0 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -3099,6 +3099,11 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi frame->this_obj = this_obj; IDispatch_AddRef(frame->this_obj); } + else if(bytecode->named_item) { + frame->this_obj = (bytecode->named_item->flags & SCRIPTITEM_CODEONLY) + ? to_disp(bytecode->named_item->script_obj) : bytecode->named_item->disp; + IDispatch_AddRef(frame->this_obj); + }
if(function_instance) frame->function_instance = jsdisp_addref(function_instance); diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index f0f8c70..a981ce8 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -1244,7 +1244,6 @@ static void test_named_items(void) SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, L"this", L"visibleCodeItem", NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); - todo_wine ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == disp, "Unexpected 'this': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var)); VariantClear(&var); @@ -1396,7 +1395,6 @@ static void test_named_items(void) SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, L"this", L"visibleItem", NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); - todo_wine ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == &visible_named_item, "Unexpected 'this': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var)); VariantClear(&var); @@ -1407,7 +1405,6 @@ static void test_named_items(void) SET_EXPECT(OnLeaveScript); hr = IActiveScriptParse_ParseScriptText(parse, L"this", L"codeOnlyItem", NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); - todo_wine ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == (IDispatch*)dispex2, "Unexpected 'this': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var)); VariantClear(&var);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 4 +++- dlls/jscript/tests/jscript.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 3e32ea0..c8d33cb 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -3034,6 +3034,8 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi }
if(flags & (EXEC_GLOBAL | EXEC_EVAL)) { + BOOL lookup_globals = (flags & EXEC_GLOBAL) && !bytecode->named_item; + for(i=0; i < function->var_cnt; i++) { TRACE("[%d] %s %d\n", i, debugstr_w(function->variables[i].name), function->variables[i].func_id); if(function->variables[i].func_id != -1) { @@ -3045,7 +3047,7 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
hres = jsdisp_propput_name(variable_obj, function->variables[i].name, jsval_obj(func_obj)); jsdisp_release(func_obj); - }else if(!(flags & EXEC_GLOBAL) || !lookup_global_members(ctx, function->variables[i].name, NULL)) { + }else if(!lookup_globals || !lookup_global_members(ctx, function->variables[i].name, NULL)) { DISPID id = 0;
hres = jsdisp_get_id(variable_obj, function->variables[i].name, fdexNameEnsure, &id); diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index a981ce8..d64d325 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -1297,7 +1297,7 @@ static void test_named_items(void) ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr); CHECK_CALLED(OnEnterScript); CHECK_CALLED(OnLeaveScript); - todo_wine CHECK_NOT_CALLED(GetIDsOfNames); + CHECK_NOT_CALLED(GetIDsOfNames);
SET_EXPECT(OnEnterScript); SET_EXPECT(OnLeaveScript);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/tests/jscript.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index d64d325..9e846eb 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -1183,6 +1183,11 @@ static void test_named_items(void) ok(visible_named_item_ref == 0, "visible_named_item_ref = %u\n", visible_named_item_ref); ok(visible_code_named_item_ref == 0, "visible_code_named_item_ref = %u\n", visible_code_named_item_ref);
+ hr = IActiveScript_GetScriptDispatch(script, L"noContext", &disp); + ok(hr == E_INVALIDARG, "GetScriptDispatch returned: %08x\n", hr); + hr = IActiveScript_GetScriptDispatch(script, L"codeONLYItem", &disp); + ok(hr == E_INVALIDARG, "GetScriptDispatch returned: %08x\n", hr); + SET_EXPECT(GetItemInfo_global_code); hr = IActiveScript_AddNamedItem(script, L"globalCodeItem", SCRIPTITEM_GLOBALMEMBERS | SCRIPTITEM_CODEONLY); ok(hr == S_OK, "AddNamedItem failed: %08x\n", hr); @@ -1265,6 +1270,8 @@ static void test_named_items(void) parse_script(parse, L"visibleItem.testCall();"); CHECK_CALLED(testCall);
+ hr = IActiveScriptParse_ParseScriptText(parse, L"function testFunc() { }", L"CodeOnlyItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "ParseScriptText returned: %08x\n", hr); SET_EXPECT(OnEnterScript); SET_EXPECT(GetIDsOfNames); SET_EXPECT(OnLeaveScript);
On 06.03.2020 14:48, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
dlls/jscript/tests/jscript.c | 7 +++++++ 1 file changed, 7 insertions(+)
This could be merged into patch 3.
Jacek