From d95a8b2bb457127b785a95c169ef16493ed2a8d1 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 1 Mar 2018 19:18:26 +0100 Subject: [PATCH] jscript: Introduce Wine-specific extension allowing IE9+ JavaScript mode implementation. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/jscript/dispex.c | 13 ++++++++++++- dlls/jscript/jscript.c | 8 ++++++-- dlls/jscript/jscript.h | 20 +++++++++++++++++++- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 40c02a064e2..ffb351e2ac3 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -90,8 +90,19 @@ static const builtin_prop_t *find_builtin_prop(jsdisp_t *This, const WCHAR *name i = (min+max)/2; r = strcmpW(name, This->builtin_info->props[i].name); - if(!r) + if(!r) { + /* Skip prop if it's available only in higher compatibility mode. */ + unsigned version = (This->builtin_info->props[i].flags & PROPF_VERSION_MASK) + >> PROPF_VERSION_SHIFT; + if(version && version > This->ctx->version) + return NULL; + + /* Skip prop if it's available only in HTML mode and we're not running in HTML mode. */ + if((This->builtin_info->props[i].flags & PROPF_HTML) && !This->ctx->html_mode) + return NULL; + return This->builtin_info->props + i; + } if(r < 0) max = i-1; diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index b7b1e1b74f2..15d81d2c539 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -55,6 +55,7 @@ typedef struct { LONG thread_id; LCID lcid; DWORD version; + BOOL html_mode; BOOL is_encode; IActiveScriptSite *site; @@ -712,6 +713,7 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface) ctx->active_script = &This->IActiveScript_iface; ctx->safeopt = This->safeopt; ctx->version = This->version; + ctx->html_mode = This->html_mode; ctx->ei.val = jsval_undefined(); heap_pool_init(&ctx->tmp_heap); @@ -920,12 +922,14 @@ static HRESULT WINAPI JScriptProperty_SetProperty(IActiveScriptProperty *iface, switch(dwProperty) { case SCRIPTPROP_INVOKEVERSIONING: - if(V_VT(pvarValue) != VT_I4 || V_I4(pvarValue) < 0 || V_I4(pvarValue) > 15) { + if(V_VT(pvarValue) != VT_I4 || V_I4(pvarValue) < 0 + || (V_I4(pvarValue) > 15 && !(V_I4(pvarValue) & SCRIPTLANGUAGEVERSION_HTML))) { WARN("invalid value %s\n", debugstr_variant(pvarValue)); return E_INVALIDARG; } - This->version = V_I4(pvarValue); + This->version = V_I4(pvarValue) & 0x1ff; + This->html_mode = (V_I4(pvarValue) & SCRIPTLANGUAGEVERSION_HTML) != 0; break; default: FIXME("Unimplemented property %x\n", dwProperty); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 1a247511acc..119d4168d12 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -34,6 +34,18 @@ #include "wine/heap.h" #include "wine/list.h" +/* + * This is Wine jscript extension for ES5 compatible mode. Native IE9+ implements + * a separated JavaScript enging in side MSHTML. We implement its features here + * and enable it when HTML flag is specified in SCRIPTPROP_INVOKEVERSIONING property. + */ +#define SCRIPTLANGUAGEVERSION_HTML 0x400 + +/* + * This is Wine jscript extension for ES5 compatible mode. Allowed only in HTML mode. + */ +#define SCRIPTLANGUAGEVERSION_ES5 0x102 + typedef struct _jsval_t jsval_t; typedef struct _jsstr_t jsstr_t; typedef struct _script_ctx_t script_ctx_t; @@ -82,6 +94,11 @@ extern HINSTANCE jscript_hinstance DECLSPEC_HIDDEN; #define PROPF_CONST 0x0800 #define PROPF_DONTDELETE 0x1000 +#define PROPF_VERSION_MASK 0x01ff0000 +#define PROPF_VERSION_SHIFT 16 +#define PROPF_HTML (SCRIPTLANGUAGEVERSION_HTML << PROPF_VERSION_SHIFT) +#define PROPF_ES5 ((SCRIPTLANGUAGEVERSION_HTML|SCRIPTLANGUAGEVERSION_ES5) << PROPF_VERSION_SHIFT) + /* * This is our internal dispatch flag informing calee that it's called directly from interpreter. * If calee is executed as interpreted function, we may let already running interpreter to take @@ -379,6 +396,7 @@ struct _script_ctx_t { IInternetHostSecurityManager *secmgr; DWORD safeopt; DWORD version; + BOOL html_mode; LCID lcid; cc_ctx_t *cc; JSCaller *jscaller; @@ -483,7 +501,7 @@ static inline BOOL is_int32(double d) static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags) { - return (ctx->version << 28) | flags; + return ((ctx->version & 0xff) << 28) | flags; } #define FACILITY_JSCRIPT 10