Module: wine Branch: master Commit: 66eb62ada690914070a7ee275a8ce253eef84a62 URL: http://source.winehq.org/git/wine.git/?a=commit;h=66eb62ada690914070a7ee275a...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Sep 16 20:44:54 2008 +0200
jscript: Added try statement implementation.
---
dlls/jscript/engine.c | 75 +++++++++++++++++++++++++++++++++++++++++-- dlls/jscript/tests/lang.js | 31 ++++++++++++++++++ 2 files changed, 102 insertions(+), 4 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 2a1bf15..f73f3bc 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -144,6 +144,15 @@ HRESULT scope_push(scope_chain_t *scope, DispatchEx *obj, scope_chain_t **ret) return S_OK; }
+static void scope_pop(scope_chain_t **scope) +{ + scope_chain_t *tmp; + + tmp = *scope; + *scope = tmp->next; + scope_release(tmp); +} + void scope_release(scope_chain_t *scope) { if(--scope->ref) @@ -713,16 +722,74 @@ HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t return E_NOTIMPL; }
-HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) +HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) { FIXME("\n"); return E_NOTIMPL; }
-HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) +/* ECMA-262 3rd Edition 12.14 */ +static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret) { - FIXME("\n"); - return E_NOTIMPL; + DispatchEx *var_disp; + VARIANT ex, val; + HRESULT hres; + + ex = rt->ei.var; + memset(&rt->ei, 0, sizeof(jsexcept_t)); + + hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp); + if(SUCCEEDED(hres)) { + hres = jsdisp_propput_name(var_disp, block->identifier, ctx->parser->script->lcid, + &ex, &rt->ei, NULL/*FIXME*/); + if(SUCCEEDED(hres)) { + hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain); + if(SUCCEEDED(hres)) { + hres = stat_eval(ctx, block->statement, rt, &val); + scope_pop(&ctx->scope_chain); + } + } + + jsdisp_release(var_disp); + } + + VariantClear(&ex); + if(FAILED(hres)) + return hres; + + *ret = val; + return S_OK; +} + +/* ECMA-262 3rd Edition 12.14 */ +HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) +{ + try_statement_t *stat = (try_statement_t*)_stat; + VARIANT val; + HRESULT hres; + + TRACE("\n"); + + hres = stat_eval(ctx, stat->try_statement, rt, &val); + if(FAILED(hres)) { + TRACE("EXCEPTION\n"); + if(!stat->catch_block) + return hres; + + hres = catch_eval(ctx, stat->catch_block, rt, &val); + if(FAILED(hres)) + return hres; + } + + if(stat->finally_statement) { + VariantClear(&val); + hres = stat_eval(ctx, stat->finally_statement, rt, &val); + if(FAILED(hres)) + return hres; + } + + *ret = val; + return S_OK; }
static HRESULT return_bool(exprval_t *ret, DWORD b) diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 7a4e4cd..d55aa17 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -236,4 +236,35 @@ ok(tmp === 1, "decremented tmp is not 1"); String.prototype.test = true; ok("".test === true, """,test is not true");
+var state = ""; +try { + ok(state === "", "try: state = " + state); + state = "try"; +}catch(ex) { + ok(false, "unexpected catch"); +} +ok(state === "try", "state = " + state + " expected try"); + +state = ""; +try { + ok(state === "", "try: state = " + state); + state = "try"; +}finally { + ok(state === "try", "funally: state = " + state); + state = "finally"; +} +ok(state === "finally", "state = " + state + " expected finally"); + +state = ""; +try { + ok(state === "", "try: state = " + state); + state = "try"; +}catch(ex) { + ok(false, "unexpected catch"); +}finally { + ok(state === "try", "funally: state = " + state); + state = "finally"; +} +ok(state === "finally", "state = " + state + " expected finally"); + reportSuccess();