Module: wine Branch: master Commit: facc2189d298ad0a76844c178fd2609e2fc7406c URL: http://source.winehq.org/git/wine.git/?a=commit;h=facc2189d298ad0a76844c178f...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Nov 30 10:14:22 2011 +0100
jscript: Use bytecode for delete on array expression implementation.
---
dlls/jscript/compile.c | 30 +++++++++++++++++++++++++ dlls/jscript/engine.c | 52 +++++++++++++++++++++++++++++++++++++++++++- dlls/jscript/engine.h | 1 + dlls/jscript/parser.y | 2 +- dlls/jscript/tests/lang.js | 7 ++++++ 5 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index b7abdda..adcd749 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -301,6 +301,34 @@ static HRESULT compile_interp_fallback(compiler_ctx_t *ctx, expression_t *expr) return S_OK; }
+static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr) +{ + HRESULT hres; + + switch(expr->expression->type) { + case EXPR_ARRAY: { + array_expression_t *array_expr = (array_expression_t*)expr->expression; + + hres = compile_expression(ctx, array_expr->member_expr); + if(FAILED(hres)) + return hres; + + hres = compile_expression(ctx, array_expr->expression); + if(FAILED(hres)) + return hres; + + if(push_instr(ctx, OP_delete) == -1) + return E_OUTOFMEMORY; + break; + } + default: + expr->expr.eval = delete_expression_eval; + return compile_interp_fallback(ctx, &expr->expr); + } + + return S_OK; +} + static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal) { switch(literal->type) { @@ -352,6 +380,8 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr) return compile_comma_expression(ctx, (binary_expression_t*)expr); case EXPR_COND: return compile_conditional_expression(ctx, (conditional_expression_t*)expr); + case EXPR_DELETE: + return compile_delete_expression(ctx, (unary_expression_t*)expr); case EXPR_DIV: return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div); case EXPR_EQ: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 48633cf..6567d68 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2498,6 +2498,53 @@ HRESULT delete_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD fla }
/* ECMA-262 3rd Edition 11.4.2 */ +static HRESULT interp_delete(exec_ctx_t *ctx) +{ + VARIANT *obj_var, *name_var; + IDispatchEx *dispex; + IDispatch *obj; + BSTR name; + BOOL ret; + HRESULT hres; + + TRACE("\n"); + + name_var = stack_pop(ctx); + obj_var = stack_pop(ctx); + + hres = to_object(ctx->parser->script, obj_var, &obj); + VariantClear(obj_var); + if(FAILED(hres)) { + VariantClear(name_var); + return hres; + } + + hres = to_string(ctx->parser->script, name_var, &ctx->ei, &name); + VariantClear(name_var); + if(FAILED(hres)) { + IDispatch_Release(obj); + return hres; + } + + hres = IDispatch_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex); + if(SUCCEEDED(hres)) { + hres = IDispatchEx_DeleteMemberByName(dispex, name, make_grfdex(ctx->parser->script, fdexNameCaseSensitive)); + ret = TRUE; + IDispatchEx_Release(dispex); + }else { + hres = S_OK; + ret = FALSE; + } + + IDispatch_Release(obj); + SysFreeString(name); + if(FAILED(hres)) + return hres; + + return stack_push_bool(ctx, ret); +} + +/* ECMA-262 3rd Edition 11.4.2 */ static HRESULT interp_void(exec_ctx_t *ctx) { VARIANT v; @@ -3469,5 +3516,8 @@ HRESULT compiled_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD fl if(FAILED(hres)) return hres;
- return (expr->eval = interp_expression_eval)(ctx, expr, flags, ei, ret); + if(expr->eval == compiled_expression_eval) + expr->eval = interp_expression_eval; + + return expr->eval(ctx, expr, flags, ei, ret); } diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 58f12c7..f2af36f 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -45,6 +45,7 @@ typedef struct _func_stack { X(add, 1, 0,0) \ X(bool, 1, ARG_INT, 0) \ X(bneg, 1, 0,0) \ + X(delete, 1, 0,0) \ X(div, 1, 0,0) \ X(double, 1, ARG_SBL, 0) \ X(eq, 1, 0,0) \ diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index 0912107..3fffbe9 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -1318,7 +1318,7 @@ static const expression_eval_t expression_eval_table[] = { compiled_expression_eval, compiled_expression_eval, compiled_expression_eval, - delete_expression_eval, + compiled_expression_eval, compiled_expression_eval, typeof_expression_eval, compiled_expression_eval, diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index c85907c..4f3d509 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -830,9 +830,16 @@ tmp = new Object(); tmp.test = false; ok((delete tmp.test) === true, "delete returned false"); ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test)); +ok(!("test" in tmp), "test is still in tmp after delete?"); for(iter in tmp) ok(false, "tmp has prop " + iter);
+tmp = new Object(); +tmp.test = false; +ok((delete tmp["test"]) === true, "delete returned false"); +ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test)); +ok(!("test" in tmp), "test is still in tmp after delete?"); + tmp.testWith = true; with(tmp) ok(testWith === true, "testWith !== true");