diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index a347101bfb0..70983fcbb26 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -17,6 +17,7 @@ */ #include "jscript.h" +#include "engine.h" #include "wine/debug.h" @@ -169,11 +170,47 @@ static HRESULT JSGlobal_escape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.1.2.1 */ static HRESULT JSGlobal_eval(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + parser_ctx_t *parser_ctx; + VARIANT *arg; + HRESULT hres; + + TRACE("\n"); + + if(!arg_cnt(dp)) { + if(retv) + V_VT(retv) = VT_EMPTY; + return S_OK; + } + + arg = get_arg(dp, 0); + if(V_VT(arg) != VT_BSTR) { + if(retv) { + V_VT(retv) = VT_EMPTY; + return VariantCopy(retv, arg); + } + return S_OK; + } + + if(!dispex->ctx->exec_ctx) { + FIXME("No active exec_ctx\n"); + return E_UNEXPECTED; + } + + TRACE("parsing %s\n", debugstr_w(V_BSTR(arg))); + hres = script_parse(dispex->ctx, V_BSTR(arg), &parser_ctx); + if(FAILED(hres)) { + FIXME("parse failed: %08x\n", hres); + return hres; + } + + hres = exec_source(dispex->ctx->exec_ctx, parser_ctx, parser_ctx->source, ei, retv); + parser_release(parser_ctx); + + return hres; } static HRESULT JSGlobal_isNaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -274,7 +311,7 @@ static const builtin_prop_t JSGlobal_props[] = { {StringW, JSGlobal_String, PROPF_CONSTR}, {VBArrayW, JSGlobal_VBArray, PROPF_METHOD}, {escapeW, JSGlobal_escape, PROPF_METHOD}, - {evalW, JSGlobal_eval, PROPF_METHOD}, + {evalW, JSGlobal_eval, PROPF_METHOD|1}, {isFiniteW, JSGlobal_isFinite, PROPF_METHOD}, {isNaNW, JSGlobal_isNaN, PROPF_METHOD}, {parseFloatW, JSGlobal_parseFloat, PROPF_METHOD}, diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 140ed0fd5a1..8a47cf42abd 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -513,4 +513,30 @@ case false: } ok(state === "default", "state = " + state); +tmp = eval("1"); +ok(tmp === 1, "eval(\"1\") !== 1"); +eval("{ ok(tmp === 1, 'eval: tmp !== 1'); } tmp = 2;"); +ok(tmp === 2, "tmp !== 2"); + +ok(eval(false) === false, "eval(false) !== false"); +ok(eval() === undefined, "eval() !== undefined"); + +tmp = eval("1", "2"); +ok(tmp === 1, "eval(\"1\", \"2\") !== 1"); + +var state = ""; +try { + ok(state === "", "try: state = " + state); + state = "try"; + eval("throwFunc(true);"); +}catch(ex) { + ok(state === "try", "catch: state = " + state); + ok(ex === true, "ex is not true"); + state = "catch"; +}finally { + ok(state === "catch", "funally: state = " + state); + state = "finally"; +} +ok(state === "finally", "state = " + state + " expected finally"); + reportSuccess(); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 1b40237cc23..ee9cccce5f9 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -241,13 +241,16 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, { switch(id) { case DISPID_GLOBAL_OK: - ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); + ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); - ok(!pvarRes, "pvarRes != NULL\n"); + if(wFlags & INVOKE_PROPERTYGET) + ok(pvarRes != NULL, "pvarRes == NULL\n"); + else + ok(!pvarRes, "pvarRes != NULL\n"); ok(pei != NULL, "pei == NULL\n"); ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));